android经验总结

Flutter模块集成到一个现有的Android项目中

2019-03-30  本文已影响5人  next_discover

1.切换分支,更新版本

flutter channel   //查看所在分支
flutter channel master  //切换至主分支
flutter upgrade //更新版本

2.创建Flutter模块

flutter create -t module my_flutter

使用As导入FlutterModule项目,选择菜单栏的 File -> New Module -> Import Flutter Module , 导入成功后,项目中的两个gradle文件会被修改。一个是 settings.gradleapp/build.gradle , 修改的内容分别如下:

settings.gradle, 最后会添加这样一段话 :

include ':app'                                     // assumed existing content
setBinding(new Binding([gradle: this]))                                 // new
evaluate(new File(                                                      // new
 settingsDir.parentFile,                                               // new
 'flutter_app/.android/include_flutter.groovy'                          // new
))   

app/build.gradle, 最后会添加这样一段话 :

dependencies {
   implementation project(':flutter')  //这是导入的Flutter的东西
   implementation fileTree(include: ['*.jar'], dir: 'libs')
   implementation 'com.android.support:appcompat-v7:27.+'
   .... //此处省略N多
}

由于 libflutter.so 的问题,或者说是安卓编译架构的问题,在编译运行后打开flutter显示的那个页面可能会出现 couldn't find libflutter.so 的问题,解决办法是只使用 armeabi-v7a, 具体配置是修改app/build.gradle 文档,如下:

android{
   defaultConfig{
       ndk {
           abiFilters "armeabi-v7a", "x86"
      }
   }
   buildTypes {
         debug {
             ndk {
               abiFilters "armeabi-v7a", "x86"
             }
         }
         release {
             ndk {
                abiFilters "armeabi-v7a"
             }   
        }
   }
}

原生页面调用flutter的例子实践

1.首先要继承FlutterActivity
2.其次没有设置contentview
3.然后通过在super之前添加FlutterMain.startInitialization(getApplicationContext());
不然会报错
4.GeneratedPluginRegistrant.registerWith(this);注册
5.通过方法名去调用方法

android 原生页面

public class MainActivity extends FlutterActivity {

    private static final String CHANNEL = "native.to.flutter";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        FlutterMain.startInitialization(getApplicationContext());
        super.onCreate(savedInstanceState);
        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {

                if(methodCall.method.equals("getBatteryLevel")){
                    int batteryLevel = getBatteryLevel();
                    if(batteryLevel != -1){
                        result.success(batteryLevel);
                    }else{
                        result.error("UNAVAILABLE", "Battery level not available.", null);
                    }

                }else  if (methodCall.method.equals("interaction")) {
                    Intent intent = new Intent(MainActivity.this, SplashActivity.class);
                    MainActivity.this.startActivity(intent);
                    result.success("success");
                } else {
                    result.notImplemented();
                }

            }
        });
        GeneratedPluginRegistrant.registerWith(this);
    }

    public int getBatteryLevel() {
        int batteryLevel = -1;
        BatteryManager systemService = (BatteryManager)getSystemService(BATTERY_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            batteryLevel = systemService.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        }else{
            Intent intent = new ContextWrapper((getApplicationContext())).registerReceiver(null,new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
            batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        }
        return batteryLevel;
    }
}

flutter页面

class _MyHomePageState extends State<MyHomePage> {
 @override
 Widget build(BuildContext context) {
   const demoPlugin = const MethodChannel('native.to.flutter');

   return new Scaffold(
     appBar: new AppBar(
       // Here we take the value from the MyHomePage object that was created by
       // the App.build method, and use it to set our appbar title.
       title: new Text(widget.title),
     ),
     body: new Center(
       child: new Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
           new RaisedButton(
             child: const Text('启动原生页面'),
             onPressed: () {
               // Perform some action
               demoPlugin.invokeMethod('interaction');
             },
           ),
         ],
       ),
     ),
   );
 }
}

关键两句话就是:

const demoPlugin = const MethodChannel('native.to.flutter');
拿到通道对象
demoPlugin.invokeMethod('interaction');
通过发送方法名字,类似反射,这样就可以调用了

这只是最简单的接入方式,这种方式存在很多问题,这样加载出来的页面会出现很久的黑屏问题,后面我们会使用闲鱼的加载框架去进行原生和flutter页面的通信。

上一篇 下一篇

猜你喜欢

热点阅读