一、概述

Flutter正式版已经出了一段时间了,作为刚入门的一个菜鸟而言,我还需要更多的学习。
最近开始的flutter项目用到了分享功能,但是到目前为止,微信,QQ等还没有出对flutter分享的SDK,这就需要用到flutter与Android和ios的原生交互。下面仅关于flutter与Android原生的交互,希望能给像我一样的菜鸟们些微的帮助(只有Android是因为ios我还没开始写哈哈哈)。

二、开始编码(以分享功能为例)

  1. 首先在Flutter端创建一个方法调用工具类,便于方法调用管理:
class ShareUtil {  ///私有构造方法  ShareUtil._();  ///其中com.example/share用于唯一识别通道名称,  /// 这个名字后边会在Android端使用到,必须跟Android端对应调用方法中的通道名称保持一致,否则无法调用  static const MethodChannel _channel =      const MethodChannel('com.example/share');  ///shareTextWithMenu对应的是Android端可以通过这个名字调用对应的方法,如果Flutter端调用方法需要传递参数,可以用map传递,  ///如下传递了一个map,其中存储text:text  static Future<dynamic> shareTextWithMenu(String text) async {    Map<dynamic, dynamic> result =        await _channel.invokeMethod('shareTextWithMenu', {"text": text});    return result;  }  ///Flutter调用是否安装了微信QQ等,需要Android端返回是否安装,用于flutter端调用方法时得到返回值。  ///这个地方我使用了回调方法onResult  static Future<dynamic> checkInstall(String platform,      {Function onResult(bool isInstall)}) async {    bool result =        await _channel.invokeMethod('checkInstall', {"platform": platform});    print("是否安装了${platform} =$result");    if (onResult != null) onResult(result);    return result;  }  ///Flutter调用三方登录,需要Android端返回是否登录成功,以及用户信息。  ///onResult中存储了是否调用成功,以及成功之后获取到的用户信息  static Future<dynamic> login(int platform,      {Function onResult(Map<String, String> userInfo)}) async {    Map<String, String> result =        await _channel.invokeMethod('login', {"platform": platform});    if (onResult != null) onResult(result);    return result;  }}    
  1. 然后在Android端对应方法:
public class SharePlugin implements MethodCallHandler, ActivityResultListener {    private final Registrar registrar;    private ShareAction mShareAction;    // 用于Activity中注册,com.secoo.yshangflutter/share和刚flutter端要相同    public static void registerWith(Registrar registrar) {        final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.example/share");        channel.setMethodCallHandler(new SharePlugin(registrar));    }    private SharePlugin(Registrar registrar) {        this.registrar = registrar;    }    /// 分享sdk初始化    private void init(Context context) {        UMConfigure.init(context, "5c2f5016b465f54424000446", "umengshare", UMConfigure.DEVICE_TYPE_PHONE, "");//58edcfeb310c93091c000be2 5965ee00734be40b580001a0        PlatformConfig.setWeixin("wxdc1e388c3822c80b", "3baf1193c85774b3fd9d18447d76cab0");        PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");        mShareAction = new ShareAction(registrar.activity()).setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.WEIXIN_FAVORITE, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE, SHARE_MEDIA.SINA);    }    ///方法调用,对应上边调用时使用的名字    @Override    public void onMethodCall(MethodCall call, Result result) {        if (call.method.equals("shareTextWithMenu")) {            String text = call.argument("text");            shareText(text, result);        } else if (call.method.equals("login")) {            int platform = call.argument("platform");            login(sharePlatForm(platform), result);        } else if (call.method.equals("checkInstall")) {            int platform = call.argument("platform");            boolean flag = UMShareAPI.get(registrar.context()).isInstall(registrar.activity(), sharePlatForm(platform));            result.success(flag);        } else {            result.notImplemented();        }    }    ///返回值都存在result中,Flutter中调用方法_channel.invokeMethod()返回值就是result中的值    private void shareText(final String text, final Result result) {        mShareAction.setShareboardclickCallback(new ShareBoardlistener() {            @Override            public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA share_media) {                new ShareAction(registrar.activity()).setPlatform(share_media)                        .withText(text)                        .setCallback(new UMShareListener() {                            @Override                            public void onStart(SHARE_MEDIA share_media) {                                LoadingDialog.showLoading(registrar.activity());                            }                            @Override                            public void onResult(SHARE_MEDIA share_media) {                                LoadingDialog.hideLoading();                                Map<String, Object> map = new HashMap<>();                                map.put("code", "000000");                                result.success(map);                            }                            @Override                            public void onError(SHARE_MEDIA share_media, Throwable throwable) {                                LoadingDialog.hideLoading();                                Toast.makeText(registrar.activity(), throwable.getMessage(), Toast.LENGTH_LONG).show();                                Map<String, Object> map = new HashMap<>();                                map.put("code", "100000");                                map.put("msg", throwable.getMessage());                                result.success(map);                            }                            @Override                            public void onCancel(SHARE_MEDIA share_media) {                                LoadingDialog.hideLoading();                                Toast.makeText(registrar.activity(), "已取消", Toast.LENGTH_LONG).show();                                Map<String, Object> map = new HashMap<>();                                map.put("status", "200000");                                result.success(map);                            }                        });            }        }).open();    }    private void login(SHARE_MEDIA platform, final Result result) {        UMShareAPI.get(registrar.activity()).getPlatformInfo(registrar.activity(), platform, new UMAuthListener() {            @Override            public void onStart(SHARE_MEDIA share_media) {                Log.e("login", "onStart");            }            @Override            public void onComplete(SHARE_MEDIA share_media, int i, Map<String, String> map) {                map.put("code", "000000");                result.success(map);            }            @Override            public void onError(SHARE_MEDIA share_media, int i, Throwable throwable) {                Map<String, Object> map = new HashMap<>();                map.put("code", "100000");                map.put("msg", throwable.getMessage());                result.success(map);            }            @Override            public void onCancel(SHARE_MEDIA share_media, int i) {                Map<String, Object> map = new HashMap<>();                map.put("code", "200000");                result.success(map);            }        });    }    private SHARE_MEDIA sharePlatForm(int index) {        final SHARE_MEDIA platform;        switch (index) {            case 0:                platform = SHARE_MEDIA.WEIXIN;                break;            case 1:                platform = SHARE_MEDIA.QQ;                break;            default:                platform = SHARE_MEDIA.QQ;                break;        }        return platform;    }    @Override    public boolean onActivityResult(int i, int i1, Intent intent) {        UMShareAPI.get(registrar.activity()).onActivityResult(i, i1, intent);        return false;    }}
  1. 在继承了FlutterActivity的Activity中注册:
public class MainActivity extends FlutterActivity {   @Override   protected void onCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);       GeneratedPluginRegistrant.registerWith(this);       registerCustomPlugin(this);   }   ///注册刚刚写的原生方法通道   private static void registerCustomPlugin(PluginRegistry registrar) {       UmengsharePlugin.registerWith(registrar.registrarFor("com.example/share"));   }}
  1. 在flutter控件中调用方法,并获取返回值:
//分享按钮 Widget _shareButton() {   return GestureDetector(     onTap: () {       Share.shareTextWithMenu("分享分享测试");       Share.checkInstall(Platform.QQ, onResult: (bool isInstall) {         print("是否安装了QQ =$isInstall");       });       Share.login(Platform.QQ, onResult: (Map<String, String> userInfo) {         print("登录用户信息=${userInfo.toString()}");       });     },     child: ...     );

三、总结

其实总结下来,flutter调用Android原生代码就一下四点

  1. flutter端创建一个MethodChannel,名字要和Android端的相同,并使用MethodChannel通过唯一方法名对应调用Android原生方法。
  2. Android端同样生成一个MethodChannel,名字要和上步骤Flutter中创建的相同。继承MethodCallHandler方法后实现onMethodCall(MethodCall call, Result result)方法,通过call拿到上步骤调用的唯一方法名实现不同的方法。
  3. 在继承了FlutterActivity的Activity中注册步骤2中实现了MethodCallHandler的通道。
  4. 开始在flutter的控件中调用原生方法。

写的比较简单,是以完成项目目前的功能为前提下匆匆记录的,希望能帮助到一些人。

更多相关文章

  1. Android中Calendar与Date的区别以及消除时区对日期操作影响的方
  2. 使用千千静听或手动创建Android播放列表的方法
  3. Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的
  4. Android操作SQLite数据库(增、删、改、查、分页等)及ListView显
  5. Android退出应用的方法总结
  6. 改进Android语音对讲系统的方法
  7. Android内存泄漏的轻松解决方法

随机推荐

  1. Android(安卓)Support兼容包详解
  2. Android中遍历文件夹、比较文件类型测试
  3. android 触摸手指动作放大和缩小图片
  4. android全屏显示
  5. Android实现文件上传功能
  6. Android(安卓)全屏
  7. android开机动画bootanimation
  8. 提示Android(安卓)dependency 'com.andro
  9. 选择框在右边的单选按钮。。
  10. android 通知Notification的使用小实例(振