asynchronous_method_channel 1.0.1+2
asynchronous_method_channel: ^1.0.1+2 copied to clipboard
The asynchronous method channel is a named channel which supports asynchronous return results for communicating with the Flutter application using asynchronous method calls.
asynchronous_method_channel #
The asynchronous method channel is a named channel which supports asynchronous return results for communicating with the Flutter application using asynchronous method calls.
Flutter Environment #
- version: v1.9.1+hotfix.6
- channel: master
Use AsynchronousMethodChannel on Android by kotlin #
The following is an example of using the kotlin coroutine for asynchronous tasks and returning results.
One thing you need to know before you officially start is that the gradle of the Android module in the Flutter app does not automatically import the packages we need, you must manually add the following code.
import io.flutter.plugins.asynchronous_method_channel.AsynchronousMethodChannel
class MainActivity: FlutterActivity() , AsynchronousMethodChannel.MethodCallHandler {
companion object{
const val CHANNEL="AsynchronousMethodChannelExample"
}
private var parentJob = Job()
private val coroutineContext: CoroutineContext
get() = parentJob + Dispatchers.Main
private val scope = CoroutineScope(coroutineContext)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
AsynchronousMethodChannel(flutterView, CHANNEL).setMethodCallHandler(this)
}
override fun onMethodCall(call: MethodCall, result: AsynchronousMethodChannel.Result) {
when (call.method) {
"getBatteryLevel" -> {
result.success(null)
scope.launch(Dispatchers.IO){
// Do something
// Perform asynchronous time-consuming tasks
// Just return results after 2 seconds
delay(2000)
// The method in AsynchronousMethodChannel.Result must be called on the main thread of the platform
scope.launch(Dispatchers.Main){
result.successAsynchronous(getBatteryLevel().toString())
}
}
}
else -> result.notImplemented()
}
}
private fun getBatteryLevel(): Int {
val batteryLevel: Int
batteryLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
} else {
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
}
return batteryLevel
}
override fun onDestroy() {
// cancel all asynchronous jobs
scope.cancel()
super.onDestroy()
}
}
Use AsynchronousMethodChannel on Flutter by dart #
The following is is an example of using AsynchronousMethodChannel in a Flutter application.
class _MyAppState extends State<MyApp> {
static final platform =
AsynchronousMethodChannel('AsynchronousMethodChannelExample');
String _batteryLevel = 'Unknown';
String _timeInfo = "";
static const style = TextStyle(
fontSize: 16,
fontFamily: "monospace",
);
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String batteryLevel;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
final sb = StringBuffer();
final startAt = DateTime.now();
sb.writeln("[start] [$startAt]");
batteryLevel =
await platform.invokeAsynchronousMethod("getBatteryLevel");
final endAt = DateTime.now();
sb.writeln("[end ] [$endAt]");
sb.writeln("[tag ] [hours:minutes:seconds:us]");
sb.writeln("[total] [${endAt.difference(startAt)}]");
_timeInfo = sb.toString();
} on PlatformException {
batteryLevel = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_batteryLevel = batteryLevel;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('AsynchronousMethodChannel example app'),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Battery level: $_batteryLevel\n', style: style),
Text(_timeInfo, style: style),
Center(
child: FlatButton(
onPressed: initPlatformState,
child: Text("Get battery level"),
),
),
],
),
),
),
);
}
}
Screenshots #
Use AsynchronousMethodChannel in tests #
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final AsynchronousMethodChannel channel =
AsynchronousMethodChannel('asynchronous_method_channel');
setUp(() {
channel.setMockAsynchronousMethodCallHandler(
(MethodCall methodCall, MockResult result) async {
switch (methodCall.method) {
case "asynchronousMethod":
// Delay 30 milliseconds to return results
Future.delayed(Duration(milliseconds: 30),
() => result.success(methodCall.arguments));
break;
case "syncMethod":
return "ok";
break;
case "getBatteryLevel":
result.success("100");
break;
}
return null;
});
});
tearDown(() {
channel.setMockAsynchronousMethodCallHandler(null);
});
test('testMethod', () async {
expect(
await channel.invokeAsynchronousMethod(
"asynchronousMethod",
{"arg": "arg1"},
),
{"arg": "arg1"},
);
expect(
await channel.invokeMethod("syncMethod"),
"ok",
);
expect(
await channel.invokeAsynchronousMethod("getBatteryLevel"),
"100",
);
});
}
Use AsynchronousMethodChannel on IOS #
Release next version.
中文文档 #
More #
Please see example.