Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit bd74fd4

Browse files
committed
[path_provider] started supporting background platform channels
1 parent c85fa03 commit bd74fd4

File tree

3 files changed

+145
-45
lines changed

3 files changed

+145
-45
lines changed

packages/path_provider/path_provider/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.0.6
2+
3+
* Added support for Background Platform Channels on Android when it is
4+
available.
5+
16
## 2.0.5
27

38
* Update minimum Flutter SDK to 2.5 and iOS deployment target to 9.0.

packages/path_provider/path_provider/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java

Lines changed: 139 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,51 +9,170 @@
99
import android.os.Build.VERSION_CODES;
1010
import android.os.Handler;
1111
import android.os.Looper;
12+
import android.util.Log;
1213
import androidx.annotation.NonNull;
1314
import com.google.common.util.concurrent.FutureCallback;
1415
import com.google.common.util.concurrent.Futures;
1516
import com.google.common.util.concurrent.SettableFuture;
1617
import com.google.common.util.concurrent.ThreadFactoryBuilder;
1718
import io.flutter.embedding.engine.plugins.FlutterPlugin;
19+
import io.flutter.plugin.common.BinaryMessenger;
1820
import io.flutter.plugin.common.MethodCall;
1921
import io.flutter.plugin.common.MethodChannel;
2022
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
2123
import io.flutter.plugin.common.MethodChannel.Result;
24+
import io.flutter.plugin.common.MethodCodec;
25+
import io.flutter.plugin.common.StandardMethodCodec;
2226
import io.flutter.util.PathUtils;
2327
import java.io.File;
28+
import java.lang.reflect.Constructor;
29+
import java.lang.reflect.Method;
2430
import java.util.ArrayList;
2531
import java.util.List;
2632
import java.util.concurrent.Callable;
2733
import java.util.concurrent.Executor;
2834
import java.util.concurrent.Executors;
2935

3036
public class PathProviderPlugin implements FlutterPlugin, MethodCallHandler {
31-
37+
static final String TAG = "PathProviderPlugin";
3238
private Context context;
3339
private MethodChannel channel;
34-
private final Executor uiThreadExecutor = new UiThreadExecutor();
35-
private final Executor executor =
36-
Executors.newSingleThreadExecutor(
37-
new ThreadFactoryBuilder()
38-
.setNameFormat("path-provider-background-%d")
39-
.setPriority(Thread.NORM_PRIORITY)
40-
.build());
40+
private PathProviderImpl impl;
41+
42+
private interface PathProviderImpl {
43+
void getTemporaryDirectory(@NonNull Result result);
44+
45+
void getApplicationDocumentsDirectory(@NonNull Result result);
46+
47+
void getStorageDirectory(@NonNull Result result);
48+
49+
void getExternalCacheDirectories(@NonNull Result result);
50+
51+
void getExternalStorageDirectories(@NonNull String directoryName, @NonNull Result result);
52+
53+
void getApplicationSupportDirectory(@NonNull Result result);
54+
}
55+
56+
private class PathProviderPlatformThread implements PathProviderImpl {
57+
private final Executor uiThreadExecutor = new UiThreadExecutor();
58+
private final Executor executor =
59+
Executors.newSingleThreadExecutor(
60+
new ThreadFactoryBuilder()
61+
.setNameFormat("path-provider-background-%d")
62+
.setPriority(Thread.NORM_PRIORITY)
63+
.build());
64+
65+
public void getTemporaryDirectory(@NonNull Result result) {
66+
executeInBackground(() -> getPathProviderTemporaryDirectory(), result);
67+
}
68+
69+
public void getApplicationDocumentsDirectory(@NonNull Result result) {
70+
executeInBackground(() -> getPathProviderApplicationDocumentsDirectory(), result);
71+
}
72+
73+
public void getStorageDirectory(@NonNull Result result) {
74+
executeInBackground(() -> getPathProviderStorageDirectory(), result);
75+
}
76+
77+
public void getExternalCacheDirectories(@NonNull Result result) {
78+
executeInBackground(() -> getPathProviderExternalCacheDirectories(), result);
79+
}
80+
81+
public void getExternalStorageDirectories(
82+
@NonNull String directoryName, @NonNull Result result) {
83+
executeInBackground(() -> getPathProviderExternalStorageDirectories(directoryName), result);
84+
}
85+
86+
public void getApplicationSupportDirectory(@NonNull Result result) {
87+
executeInBackground(() -> PathProviderPlugin.this.getApplicationSupportDirectory(), result);
88+
}
89+
90+
private <T> void executeInBackground(Callable<T> task, Result result) {
91+
final SettableFuture<T> future = SettableFuture.create();
92+
Futures.addCallback(
93+
future,
94+
new FutureCallback<T>() {
95+
public void onSuccess(T answer) {
96+
result.success(answer);
97+
}
98+
99+
public void onFailure(Throwable t) {
100+
result.error(t.getClass().getName(), t.getMessage(), null);
101+
}
102+
},
103+
uiThreadExecutor);
104+
executor.execute(
105+
() -> {
106+
try {
107+
future.set(task.call());
108+
} catch (Throwable t) {
109+
future.setException(t);
110+
}
111+
});
112+
}
113+
}
114+
115+
private class PathProviderBackgroundThread implements PathProviderImpl {
116+
public void getTemporaryDirectory(@NonNull Result result) {
117+
result.success(getPathProviderTemporaryDirectory());
118+
}
119+
120+
public void getApplicationDocumentsDirectory(@NonNull Result result) {
121+
result.success(getPathProviderApplicationDocumentsDirectory());
122+
}
123+
124+
public void getStorageDirectory(@NonNull Result result) {
125+
result.success(getPathProviderStorageDirectory());
126+
}
127+
128+
public void getExternalCacheDirectories(@NonNull Result result) {
129+
result.success(getPathProviderExternalCacheDirectories());
130+
}
131+
132+
public void getExternalStorageDirectories(
133+
@NonNull String directoryName, @NonNull Result result) {
134+
result.success(getPathProviderExternalStorageDirectories(directoryName));
135+
}
136+
137+
public void getApplicationSupportDirectory(@NonNull Result result) {
138+
result.success(PathProviderPlugin.this.getApplicationSupportDirectory());
139+
}
140+
}
41141

42142
public PathProviderPlugin() {}
43143

144+
private void setup(BinaryMessenger messenger, Context context) {
145+
String channelName = "plugins.flutter.io/path_provider";
146+
try {
147+
Class methodChannelClass = Class.forName("io.flutter.plugin.common.MethodChannel");
148+
Class taskQueueClass = Class.forName("io.flutter.plugin.common.BinaryMessenger$TaskQueue");
149+
Method makeBackgroundTaskQueue = messenger.getClass().getMethod("makeBackgroundTaskQueue");
150+
Object taskQueue = makeBackgroundTaskQueue.invoke(messenger);
151+
Constructor<MethodChannel> constructor =
152+
methodChannelClass.getConstructor(
153+
BinaryMessenger.class, String.class, MethodCodec.class, taskQueueClass);
154+
channel =
155+
constructor.newInstance(messenger, channelName, StandardMethodCodec.INSTANCE, taskQueue);
156+
impl = new PathProviderBackgroundThread();
157+
Log.d(TAG, "use taskqueues");
158+
} catch (Exception ex) {
159+
channel = new MethodChannel(messenger, channelName);
160+
impl = new PathProviderPlatformThread();
161+
Log.d(TAG, "don't use taskqueues");
162+
}
163+
this.context = context;
164+
channel.setMethodCallHandler(this);
165+
}
166+
44167
@SuppressWarnings("deprecation")
45168
public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) {
46169
PathProviderPlugin instance = new PathProviderPlugin();
47-
instance.channel = new MethodChannel(registrar.messenger(), "plugins.flutter.io/path_provider");
48-
instance.context = registrar.context();
49-
instance.channel.setMethodCallHandler(instance);
170+
instance.setup(registrar.messenger(), registrar.context());
50171
}
51172

52173
@Override
53174
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
54-
channel = new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/path_provider");
55-
context = binding.getApplicationContext();
56-
channel.setMethodCallHandler(this);
175+
setup(binding.getBinaryMessenger(), binding.getApplicationContext());
57176
}
58177

59178
@Override
@@ -62,52 +181,28 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
62181
channel = null;
63182
}
64183

65-
private <T> void executeInBackground(Callable<T> task, Result result) {
66-
final SettableFuture<T> future = SettableFuture.create();
67-
Futures.addCallback(
68-
future,
69-
new FutureCallback<T>() {
70-
public void onSuccess(T answer) {
71-
result.success(answer);
72-
}
73-
74-
public void onFailure(Throwable t) {
75-
result.error(t.getClass().getName(), t.getMessage(), null);
76-
}
77-
},
78-
uiThreadExecutor);
79-
executor.execute(
80-
() -> {
81-
try {
82-
future.set(task.call());
83-
} catch (Throwable t) {
84-
future.setException(t);
85-
}
86-
});
87-
}
88-
89184
@Override
90185
public void onMethodCall(MethodCall call, @NonNull Result result) {
91186
switch (call.method) {
92187
case "getTemporaryDirectory":
93-
executeInBackground(() -> getPathProviderTemporaryDirectory(), result);
188+
impl.getTemporaryDirectory(result);
94189
break;
95190
case "getApplicationDocumentsDirectory":
96-
executeInBackground(() -> getPathProviderApplicationDocumentsDirectory(), result);
191+
impl.getApplicationDocumentsDirectory(result);
97192
break;
98193
case "getStorageDirectory":
99-
executeInBackground(() -> getPathProviderStorageDirectory(), result);
194+
impl.getStorageDirectory(result);
100195
break;
101196
case "getExternalCacheDirectories":
102-
executeInBackground(() -> getPathProviderExternalCacheDirectories(), result);
197+
impl.getExternalCacheDirectories(result);
103198
break;
104199
case "getExternalStorageDirectories":
105200
final Integer type = call.argument("type");
106201
final String directoryName = StorageDirectoryMapper.androidType(type);
107-
executeInBackground(() -> getPathProviderExternalStorageDirectories(directoryName), result);
202+
impl.getExternalStorageDirectories(directoryName, result);
108203
break;
109204
case "getApplicationSupportDirectory":
110-
executeInBackground(() -> getApplicationSupportDirectory(), result);
205+
impl.getApplicationSupportDirectory(result);
111206
break;
112207
default:
113208
result.notImplemented();

packages/path_provider/path_provider/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: path_provider
22
description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories.
33
repository: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22
5-
version: 2.0.5
5+
version: 2.0.6
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)