flutter使用java,flutter怎样集成原生模块android版,以及现阶段会遇到的坑和解决方法...

前言

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

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

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

创建一个plugin

命令行中运行

flutter create --template=plugin futter_baidu_map

在android-studio打开项目

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

文档地址:

这里选择想要的模块:

bVbbXJQ?w=532&h=808

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

bVbbXHX?w=508&h=384

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

bVbbXJZ?w=706&h=890

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

bVbbXIY?w=1224&h=862

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

bVbbXI7?w=2092&h=854

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

bVbbXJi?w=818&h=470

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

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

bVbbXSt?w=1484&h=1082

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

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

bVbbXXm?w=1744&h=858

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

bVbbXXr?w=2170&h=1166

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

bVbbXX2?w=192&h=198

继续往下搞:

集成定位功能

初始化地图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("百度地图加载失败...");

}

}

运行输出:

bVbbX5d?w=650&h=146

监听地理位置(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("百度地图加载失败...");

}

}

输出:

bVbbYgA?w=1044&h=162

其他项目使用这个模块:

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

bVbbYho?w=480&h=268

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

bVbbYh6?w=864&h=528

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

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

代码:

如有疑问,请加qq群854192563讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值