Browse Source

Load icons on main thread (#2536)

Only reason to offload icon loading to background thread is to avoid
supposed network on main thread calls which happen only in debug since
icons are passed loaded from localhost.
Guy Carmeli 6 years ago
parent
commit
3dd96a94ef
No account linked to committer's email address

+ 3
- 1
lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java View File

13
 public abstract class NavigationApplication extends Application implements ReactApplication {
13
 public abstract class NavigationApplication extends Application implements ReactApplication {
14
 
14
 
15
 	private ReactGateway reactGateway;
15
 	private ReactGateway reactGateway;
16
+	public static NavigationApplication instance;
16
 
17
 
17
 	@Override
18
 	@Override
18
 	public void onCreate() {
19
 	public void onCreate() {
19
 		super.onCreate();
20
 		super.onCreate();
20
-		reactGateway = new ReactGateway(this, isDebug(), createAdditionalReactPackages());
21
+        instance = this;
22
+        reactGateway = new ReactGateway(this, isDebug(), createAdditionalReactPackages());
21
 	}
23
 	}
22
 
24
 
23
 	public ReactGateway getReactGateway() {
25
 	public ReactGateway getReactGateway() {

+ 1
- 1
lib/android/app/src/main/java/com/reactnativenavigation/presentation/OptionsPresenter.java View File

23
     }
23
     }
24
 
24
 
25
     public void applyOptions(Options options) {
25
     public void applyOptions(Options options) {
26
-        applyTopBarOptions(options.topBarOptions);
27
         applyButtons(options.topBarOptions.leftButtons, options.topBarOptions.rightButtons);
26
         applyButtons(options.topBarOptions.leftButtons, options.topBarOptions.rightButtons);
27
+        applyTopBarOptions(options.topBarOptions);
28
         applyTopTabsOptions(options.topTabsOptions);
28
         applyTopTabsOptions(options.topTabsOptions);
29
         applyTopTabOptions(options.topTabOptions);
29
         applyTopTabOptions(options.topTabOptions);
30
     }
30
     }

+ 42
- 39
lib/android/app/src/main/java/com/reactnativenavigation/utils/ImageUtils.java View File

8
 import android.net.Uri;
8
 import android.net.Uri;
9
 import android.os.StrictMode;
9
 import android.os.StrictMode;
10
 import android.support.annotation.NonNull;
10
 import android.support.annotation.NonNull;
11
+import android.support.annotation.Nullable;
11
 
12
 
13
+import com.reactnativenavigation.NavigationApplication;
14
+
15
+import java.io.FileNotFoundException;
12
 import java.io.IOException;
16
 import java.io.IOException;
13
 import java.io.InputStream;
17
 import java.io.InputStream;
14
 import java.net.URL;
18
 import java.net.URL;
21
 		void onError(Throwable error);
25
 		void onError(Throwable error);
22
 	}
26
 	}
23
 
27
 
24
-	public static void tryLoadIcon(final Context context, final String uri, final ImageLoadingListener listener) {
25
-		if (uri == null) {
26
-			if (listener != null) {
27
-				listener.onError(new IllegalArgumentException("Uri is null"));
28
-			}
29
-			return;
30
-		}
31
-		runWorkerThread(new Runnable() {
32
-			@Override
33
-			public void run() {
34
-				loadIcon(context, uri, listener);
35
-			}
36
-		});
37
-	}
28
+	public static void loadIcon(final Context context, final String uri, final ImageLoadingListener listener) {
29
+        try {
30
+            StrictMode.ThreadPolicy threadPolicy = adjustThreadPolicyDebug();
31
+            
32
+            InputStream is = openStream(context, uri);
33
+            Bitmap bitmap = BitmapFactory.decodeStream(is);
34
+            Drawable drawable = new BitmapDrawable(context.getResources(), bitmap);
35
+            listener.onComplete(drawable);
38
 
36
 
39
-	private static void loadIcon(Context context, String uri, final ImageLoadingListener listener) {
40
-		try {
41
-			InputStream is = null;
42
-			if (uri.contains("http")) {
43
-				URL url = new URL(uri);
44
-				is = url.openStream();
45
-			} else {
46
-				is = context.getContentResolver().openInputStream(Uri.parse(uri));
47
-			}
37
+            restoreThreadPolicyDebug(threadPolicy);
38
+        } catch (IOException e) {
39
+            listener.onError(e);
40
+        }
41
+    }
48
 
42
 
49
-			Bitmap bitmap = BitmapFactory.decodeStream(is);
50
-			Drawable drawable = new BitmapDrawable(context.getResources(), bitmap);
51
-			if (listener != null) {
52
-				listener.onComplete(drawable);
53
-			}
54
-		} catch (IOException e) {
55
-			if (listener != null) {
56
-				listener.onError(e);
57
-			} else {
58
-				e.printStackTrace();
59
-			}
60
-		}
61
-	}
43
+    private static StrictMode.ThreadPolicy adjustThreadPolicyDebug() {
44
+        StrictMode.ThreadPolicy threadPolicy = null;
45
+        if (NavigationApplication.instance.isDebug()) {
46
+            threadPolicy = StrictMode.getThreadPolicy();
47
+            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());
48
+        }
49
+        return threadPolicy;
50
+    }
62
 
51
 
63
-	private static void runWorkerThread(Runnable runnable) {
64
-		new Thread(runnable).start();
65
-	}
52
+    private static void restoreThreadPolicyDebug(@Nullable StrictMode.ThreadPolicy threadPolicy) {
53
+        if (NavigationApplication.instance.isDebug() && threadPolicy != null) {
54
+            StrictMode.setThreadPolicy(threadPolicy);
55
+        }
56
+    }
57
+
58
+    private static InputStream openStream(Context context, String uri) throws IOException {
59
+        return uri.contains("http") ? remoteUrl(uri) : localFile(context, uri);
60
+    }
61
+
62
+    private static InputStream remoteUrl(String uri) throws IOException {
63
+        return new URL(uri).openStream();
64
+    }
65
+
66
+    private static InputStream localFile(Context context, String uri) throws FileNotFoundException {
67
+        return context.getContentResolver().openInputStream(Uri.parse(uri));
68
+    }
66
 }
69
 }

+ 7
- 13
lib/android/app/src/main/java/com/reactnativenavigation/views/TitleBarButton.java View File

57
 			return;
57
 			return;
58
 		}
58
 		}
59
 
59
 
60
-		ImageUtils.tryLoadIcon(context, button.icon.get(), new ImageUtils.ImageLoadingListener() {
60
+		ImageUtils.loadIcon(context, button.icon.get(), new ImageUtils.ImageLoadingListener() {
61
 			@Override
61
 			@Override
62
 			public void onComplete(@NonNull Drawable drawable) {
62
 			public void onComplete(@NonNull Drawable drawable) {
63
 				icon = drawable;
63
 				icon = drawable;
64
-				UiUtils.runOnMainThread(() -> {
65
-                    setIconColor();
66
-                    setNavigationClickListener();
67
-                    toolbar.setNavigationIcon(icon);
68
-                });
64
+                setIconColor();
65
+                setNavigationClickListener();
66
+                toolbar.setNavigationIcon(icon);
69
 			}
67
 			}
70
 
68
 
71
 			@Override
69
 			@Override
72
 			public void onError(Throwable error) {
70
 			public void onError(Throwable error) {
73
-				//TODO: handle
74
 				error.printStackTrace();
71
 				error.printStackTrace();
75
 			}
72
 			}
76
 		});
73
 		});
77
 	}
74
 	}
78
 
75
 
79
 	private void applyIcon(Context context, final MenuItem menuItem) {
76
 	private void applyIcon(Context context, final MenuItem menuItem) {
80
-		ImageUtils.tryLoadIcon(context, button.icon.get(), new ImageUtils.ImageLoadingListener() {
77
+		ImageUtils.loadIcon(context, button.icon.get(), new ImageUtils.ImageLoadingListener() {
81
 			@Override
78
 			@Override
82
 			public void onComplete(@NonNull Drawable drawable) {
79
 			public void onComplete(@NonNull Drawable drawable) {
83
 				icon = drawable;
80
 				icon = drawable;
84
-				UiUtils.runOnMainThread(() -> {
85
-                    menuItem.setIcon(icon);
86
-                    setIconColor();
87
-                });
81
+                menuItem.setIcon(icon);
82
+                setIconColor();
88
 			}
83
 			}
89
 
84
 
90
 			@Override
85
 			@Override
91
 			public void onError(Throwable error) {
86
 			public void onError(Throwable error) {
92
-				//TODO: handle
93
 				error.printStackTrace();
87
 				error.printStackTrace();
94
 			}
88
 			}
95
 		});
89
 		});