博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
flutter怎样集成原生模块android版,以及现阶段会遇到的坑和解决方法
阅读量:5819 次
发布时间:2019-06-18

本文共 7940 字,大约阅读时间需要 26 分钟。

前言

在开发一个上线的app过程中,单纯的依赖某一种框架在当前基本不存在,不可避免的需要多种技术参与。

本文以集成百度地图为例,详细讲述如何在flutter中集成android原生模块,flutter怎么调用java,以及java如何通知flutter。

为什么以百度地图为例呢,百度地图含jar和so,比较全面,又是一个视图型的框架,比较容易看到结果。

创建一个plugin

命令行中运行

flutter create --template=plugin futter_baidu_map 复制代码

在android-studio打开项目

按照百度地图官方文档集成android版本

文档地址:

http://lbsyun.baidu.com/index.php?title=androidsdk/guide/create-project/ak

这里选择想要的模块:

下载之后是这样一个结构:

全部放到刚才创建项目的android项目的libs目录中,这个目录如果不存在需要创建一下,最后的目录结构如下:

4071650091-5b17c0ba3d00d_articlex.png

修改一下build.gradle,增加依赖

1524805254-5b17bf215a515_articlex.png

打开FlutterBaiduMapPlugin编辑,初次打开会出现这个提示:

3967820436-5b17bf6e93291_articlex.png

点击一下右上角的 "Setup SDK",

1436375478-5b17bfa31bd94_articlex.png

这里按需选择配置,这里我选择了Anroid API 27 Platform.

下面编辑我们想要的功能,这个时候坑来了:

3953759209-5b17d2b16342c_articlex.png

这里虽然导入了百度地图的库,依赖也加了,但是android studio居然识别不出来!!!!这个问题困扰了我n久,甚至还搞了一套flutter的fake代码放在其他项目中。

转折来了......今天忽然发现这里有个菜单:

1444258350-5b17da130025a_articlex.png

点击一下,android-studio会新开一个项目:

84776404-5b17da66db281_articlex.png

神奇的发现,那些红色的不能识别的代码都消失了!!!

继续往下搞:

集成定位功能

按照这里的指示增加一些配置,申请一个key,这里就不细说了 http://lbsyun.baidu.com/index.php?title=androidsdk/guide/create-project/hellomap

初始化地图SDK(flutter调用java)_

修改java文件:com.example.flutterbaidumap.FlutterBaiduMapPlugin

public class FlutterBaiduMapPlugin implements MethodCallHandler {  private Activity activity;  private LocationManager mSysLocManager;  public FlutterBaiduMapPlugin(Activity activity) {    this.activity = activity;  }  /**   * Plugin registration.   */  public static void registerWith(Registrar registrar) {    final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_baidu_map");    channel.setMethodCallHandler(new FlutterBaiduMapPlugin( registrar.activity() ));  }  @Override  public void onMethodCall(MethodCall call, Result result) {    if (call.method.equals("init")) {      SDKInitializer.initialize(activity.getApplicationContext());      try {        if (mSysLocManager == null) {          /** 获取系统的定位服务管理类*/          mSysLocManager = (LocationManager) JNIInitializer.getCachedContext()                  .getSystemService(Context.LOCATION_SERVICE);        }        //成功返回true        result.success(true);      } catch (Exception e) {        // 失败返回false        result.success(false );      }    } else {      result.notImplemented();    }  }}复制代码

在dart中调用:修改flutter_baidu_map.dart

import 'dart:async';import 'package:flutter/services.dart';class FlutterBaiduMap {  static const MethodChannel _channel =      const MethodChannel('flutter_baidu_map');  static Future
init() async { return await _channel.invokeMethod('init'); }}复制代码

在example的main.dart中这么调用

@override  initState() {    initBaidu();    super.initState();  }  void initBaidu() async{    bool result = await FlutterBaiduMap.init();    if(result){      print("百度地图加载成功...");    }else{      print("百度地图加载失败...");    }  }复制代码

运行输出:

238120750-5b1801e106aa6_articlex.png

监听地理位置(java通知flutter)

java文件增加判断,并增加一个MethodChannel的引用,向flutter发送消息全靠他了。

package com.example.flutterbaidumap;import android.app.Activity;import android.content.Context;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Build;import android.os.Bundle;import io.flutter.plugin.common.MethodChannel;import io.flutter.plugin.common.MethodChannel.MethodCallHandler;import io.flutter.plugin.common.MethodChannel.Result;import io.flutter.plugin.common.MethodCall;import io.flutter.plugin.common.PluginRegistry.Registrar;import com.baidu.mapapi.JNIInitializer;import com.baidu.mapapi.SDKInitializer;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;/** * FlutterBaiduMapPlugin */public class FlutterBaiduMapPlugin implements MethodCallHandler {    private Activity activity;    private LocationManager mSysLocManager;    private MethodChannel channel;    public FlutterBaiduMapPlugin(Activity activity,MethodChannel channel) {        this.activity = activity;        this.channel = channel;    }    /**     * Plugin registration.     */    public static void registerWith(Registrar registrar) {        final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_baidu_map");        channel.setMethodCallHandler(new FlutterBaiduMapPlugin(registrar.activity(),channel));    }    @Override    public void onMethodCall(final MethodCall call, final Result result) {        if (call.method.equals("init")) {            SDKInitializer.initialize(activity.getApplicationContext());            try {                if (mSysLocManager == null) {                    /** 获取系统的定位服务管理类*/                    mSysLocManager = (LocationManager) JNIInitializer.getCachedContext()                            .getSystemService(Context.LOCATION_SERVICE);                }                //成功返回true                result.success(true);            } catch (Exception e) {                // 失败返回false                result.success(false);            }        } else if (call.method.equals("startLocation")) {            mSysLocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener);            result.success(true);        } else {            result.notImplemented();        }    }    private LocationListener listener = new LocationListener() {        @Override        public void onLocationChanged(Location location) {            Map
data = new HashMap
(); data.put("latitude",location.getLatitude()); data.put("longitude",location.getLongitude()); data.put("result", "onLocationChanged"); channel.invokeMethod("onLocation" ,data ); } @Override public void onStatusChanged(String s, int i, Bundle bundle) { Map
data = new HashMap
(); data.put("result", "status"); channel.invokeMethod("onLocation" ,data ); } @Override public void onProviderEnabled(String s) { Map
data = new HashMap
(); data.put("result", "onProviderEnabled"); channel.invokeMethod("onLocation" ,data ); } @Override public void onProviderDisabled(String s) { Map
data = new HashMap
(); data.put("result", "onProviderDisabled"); channel.invokeMethod("onLocation" ,data ); } };}复制代码

增加调用,修改flutter_baidu_map.dart,这里需要使用StreamController的add方法增加事件,并使用StreamController的stream增加一个监听:

static Future
init() async { _channel.setMethodCallHandler(handler); //注意这里需要设置一下监听函数 return await _channel.invokeMethod('init'); } static StreamController
_locationUpdateStreamController = new StreamController.broadcast(); static Stream get locationUpdate=>_locationUpdateStreamController.stream; static Future
handler(MethodCall call) { String method = call.method; switch (method) { case "onLocation": { _locationUpdateStreamController.add( call.arguments ); } break; } return new Future.value(""); }复制代码

修改main.dart

void initBaidu() async{    bool result = await FlutterBaiduMap.init();    if(result){      print("百度地图加载成功...");     await FlutterBaiduMap.startLocation();      print("正在监听...");        //这里监听位置改变      FlutterBaiduMap.locationUpdate.listen(  (Map data){        print("获取到百度地图定位:$data");      });    }else{      print("百度地图加载失败...");    }  }复制代码

输出:

其他项目使用这个模块:

一种方法是发布到https://pub.dartlang.org 上去,参考官网指引:https://flutter.io/developing-packages/#publish

另一种是这边要讲的:本地依赖

把使用flutter_baidu_map模块的项目放在同一层目录中(实际上这个也没有必要),编辑调用方的pubspec.yaml,增加依赖:

没错,就这么简单,然后在这个项目中运行一下:

flutter package get 复制代码

然后就可以愉快的使用了。

总结一下:

1、flutter调用java:

创建plugin,并在java的Plugin实现类中实现onMethodCall方法

2、java调用flutter:

在java中使用MethodChannel调用方法,并在dart中使用StreamController结合StreamController.stream实现监听。

3、其他项目使用plugin 编辑pubspec.yaml,增加本地依赖,或者发布到pub.dartlang.org

代码:

https://github.com/jzoom/flutter-example/tree/master/flutter_baidu_map

转载地址:http://rzzdx.baihongyu.com/

你可能感兴趣的文章
浮点数内存如何存储的
查看>>
贪吃蛇
查看>>
EventSystem
查看>>
用WINSOCK API实现同步非阻塞方式的网络通讯
查看>>
玩一玩博客,嘿嘿
查看>>
P1352 没有上司的舞会
查看>>
ios11文件夹
查看>>
【HLOJ 559】好朋友的题
查看>>
Electric Fence(皮克定理)
查看>>
【状压DP】【UVA11825】 Hackers' Crackdown
查看>>
nvl 在mysql中如何处理
查看>>
MyEclipse 快捷键
查看>>
快速傅里叶变换FFT
查看>>
大数据常用基本算法
查看>>
JavaScript学习笔记(十三)——生成器(generator)
查看>>
hibernate保存失败
查看>>
MySQL增量订阅&消费组件Canal POC
查看>>
Sqlite多线程
查看>>
数据结构-时间复杂度
查看>>
对象与字符串相互转换
查看>>