当前位置: 首页 > wzjs >正文

光电信息科学与工程自动seo系统

光电信息科学与工程,自动seo系统,dw网页制作教程视频简单第三期,wordpress图片cdn目录 步骤说明 1.打开android文件夹 2.新建Activity 3.原生代码编写 4.Activity中注册插件 5.flutter中插件初始化和封装 6.flutter页面中使用插件 传参补充 代码参考 最近需要给一个Flutter项目加个apk完整性检测,需要去拿到当前安装apk的md5数值&#xf…

目录

步骤说明

1.打开android文件夹

2.新建Activity

3.原生代码编写

4.Activity中注册插件

5.flutter中插件初始化和封装

6.flutter页面中使用插件

传参补充

代码参考


最近需要给一个Flutter项目加个apk完整性检测,需要去拿到当前安装apk的md5数值,由于Flutter中无法实现,需要调用原生Android代码才能实现,于是花了些时间研究了下插件的实现,特此记录

步骤说明

1.打开android文件夹

flutter中有个ios和android的文件夹,分别对应的Android和Ios的原生代码

我们想要实现FLutter调用原生代码,在里面写原生代码即可

在android文件夹中,新建有个类,Android可以选择Java或者是Kotlin代码编写即可

android目录结构其实就是常见的Android项目目录

然后使用Android Studio打开,右键菜单,选择flutter -> Open Android module in Android Studio

之后可以看到已经像Android开发一样打开了一个项目(当然,这里你也可以自己使用Android Studio去选择那个android文件夹,将其当做项目打开即可)

2.新建Activity

此Activity需要继承FlutterActivity,并重写configureFlutterEngine方法,在此方法中进行插件的初始化

public class MainActivity extends FlutterActivity {@Overridepublic void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {//插件实例的注册...//这个是必写,别删除!!GeneratedPluginRegistrant.registerWith(flutterEngine);}
}

那么这里需要插件的实例,插件的实例怎么来呢?其实就是自己写个类,然后实现Flutter提供的FlutterPlugin接口

3.原生代码编写

新建一个类,实现FlutterPlugin接口,创建一个MethodChannel对象,利用此对象的setMethodCallHandler方法设置方法处理回调,里面通过判断方法名来调我们原生写的方法

public class MyTestPlugin implements FlutterPlugin {@Overridepublic void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {//可以利用binding对象获取到Android中需要的Context对象//Context applicationContext = binding.getApplicationContext();//设置channel名称,之后flutter中也要一样MethodChannel channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), "test-plugin");//把当前的MethodCallHandler设置channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {String method = call.method;if (method.equals("getText")) {//调用原生的方法,这里为了方便,我就把方法写在当前类了String str = getText();//将结果返回给flutterresult.success(str);//这里也有error的方法,可以看情况使用//result.error("code", "message", "detail");} else {//Flutter传过来id方法名没有找到,就调此方法result.notImplemented();}}});}private String getText() {return "hello world";}@Overridepublic void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}
}

如果你想要一个Application的context上下文对象,可以在onAttachedToEngine()方法中使用binding的getApplicationContext()方法获取,如下代码

Context applicationContext = binding.getApplicationContext();

如果是想要获取当前Activity的context对象,可以让当前类实现ActivityAware接口,不过略显繁琐,一般用Application的context对象应该可以满足大部分要求了,看情况选择吧

private Context context;
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {context = binding.getActivity();
}@Override
public void onDetachedFromActivityForConfigChanges() {}@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {}@Override
public void onDetachedFromActivity() {
context = null;
}
4.Activity中注册插件

之前在第二步中的Activity中,补上注册的代码

public class MainActivity extends FlutterActivity {@Overridepublic void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {//插件实例的注册...flutterEngine.getPlugins().add(new MyTestPlugin());GeneratedPluginRegistrant.registerWith(flutterEngine);}
}
5.flutter中插件初始化和封装

在flutter中创建一个文件,文件名和class名任意,只是用来声明和初始化上述的Java类

class Md5Plugin{//注意,这里的名称需要和Android原生中定义的一样static const MethodChannel _channel = MethodChannel("apk_md5");static Future<String> getMd5() async{//传递一个方法名,即调用Android的原生方法return await _channel.invokeMethod("getMd5");}}

还记得之前写的方法名的判断吗?这里就是传一个方法名,之后就会触发回调,之后即可得到返回结果

PS:注意,调Android原生的方法都是异步操作!

6.flutter页面中使用插件
之后在对应的page文件对应代码处中调用即可
Md5Plugin.getMd5().then(value=>{//相关操作
});

如果想使用同步代码,可以这样写

var result = Md5Plugin.getMd5()

PS:测试的时候注意,如果是改了原生层代码(Java或Kotlin),最好将项目重新运行,不要使用Flutter的热重载功能(除非你只动了flutter的代码)

传参补充

上述的例子中,并没有涉及到传参,这里再补充讲解下我自己的研究使用

这里只讲Flutter如何给Android原生传参

FLutter中调用方法(即上述的第五步操作):

class Md5Plugin{//注意,这里的名称需要和Android原生中定义的一样static const MethodChannel _channel = MethodChannel("apk_md5");static Future<String> getMd5() async{//传字符串给Androidvar param = "hello";//传递一个方法名,即调用Android的原生方法//注意这里的第二个参数return await _channel.invokeMethod("getMd5",param);}
}

Android中的接收(上述的第三步):

在判断方法名之后,即可通过对应的方法获取数据(需要类型转换)

public class MyTestPlugin implements FlutterPlugin {@Overridepublic void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {...//把当前的MethodCallHandler设置channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {String method = call.method;if (method.equals("getText")) {//注意这里的获取数据(强转)String packageName = (String)call.arguments;省略...} else {//Flutter传过来id方法名没有找到,就调此方法result.notImplemented();}}});}...
}

上述的代码只是传单个数据,如果是要穿多个数据要怎么办呢?

由于invokeMethod()方法里只支持传单个数据,所以我们需要传map或是json格式的数据给到Android原生

Flutter发送数据:

var param = {"myKey":"hello"}//传递一个方法名,即调用Android的原生方法
//注意这里的第二个参数
return await _channel.invokeMethod("getMd5",param);

Android接收数据:


String packageName = call.argument("myKey");

这里有点要注意,call中有个arguments属性和arguments()方法,如下图

flutter中传过来的数据是map或json的,就得用arguments()来获取参数据;否则就是使用arguments属性

当然,如果传过来的数据是map或json类型,call提供了一个方便快捷的方法,我们可以直接使用argument(key)来直接获取key对应的数值**(注意这里也需要类型强转,注意类型需要对应)**

最后这里给出Flutter与Java的对应的类型表:

Dart

Android

null

null

bool

java.lang.Boolean

int

java.lang.Integer

int, if 32 bits not enough

java.lang.Long

double

java.lang.Double

String

java.lang.String

Uint8List

byte[]

Int32List

int[]

Int64List

long[]

Float64List

double[]

List

java.util.ArrayList

Map

java.util.HashMap

代码参考

package com.example.taiji_lianjiang.checkplugin;import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;import com.example.taiji_lianjiang.BuildConfig;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;public class ApkMd5CheckPlugin implements MethodChannel.MethodCallHandler, FlutterPlugin, ActivityAware {public static ApkMd5CheckPlugin getInstance() {return new ApkMd5CheckPlugin();}private MethodChannel channel;private Activity context;@Overridepublic void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {//设置channel名称,之后flutter中也要一样channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), "apk_md5");//把当前的MethodCallHandler设置channel.setMethodCallHandler(this);}@Overridepublic void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}@Overridepublic void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {String method = call.method;if (method.equals("getMd5")) {String md5 = getMd5(context);if (!TextUtils.isEmpty(md5)) {result.success(md5);} else {result.error("101", "获取md5失败", "");}} else {result.notImplemented();}}//获取你重新自身的安装包位置 一般在/data/app/包名/xxx.apkprivate String getApkPath(Context context) {try {PackageInfo packageInfo = context.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, PackageManager.GET_META_DATA);ApplicationInfo applicationInfo = packageInfo.applicationInfo;return applicationInfo.publicSourceDir; // 获取当前apk包的绝对路径} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}return "";}//获取hash值 整个apk的 注意 这里代码不太严谨 demo随便敲的 跑通就行了private String getMd5(Context context) {String apkPath = getApkPath(context);StringBuffer sb = new StringBuffer("");try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(readFileToByteArray(new File(apkPath)));byte b[] = md.digest();int d;for (int i = 0; i < b.length; i++) {d = b[i];if (d < 0) {d = b[i] & 0xff;// 与上一行效果等同// i += 256;}if (d < 16)sb.append("0");sb.append(Integer.toHexString(d));}} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return sb.toString().toUpperCase();}private byte[] readFileToByteArray(File file) throws IOException {InputStream in = null;try {in = new FileInputStream(file);return toByteArray(in, file.length());} finally {in.close();}}private byte[] toByteArray(InputStream input, long size) throws IOException {if (size > Integer.MAX_VALUE) {throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);}return toByteArray(input, (int) size);}private byte[] toByteArray(InputStream input, int size) throws IOException {if (size < 0) {throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);}if (size == 0) {return new byte[0];}byte[] data = new byte[size];int offset = 0;int readed;while (offset < size && (readed = input.read(data, offset, size - offset)) != -1) {offset += readed;}if (offset != size) {throw new IOException("Unexpected readed size. current: " + offset + ", excepted: " + size);}return data;}@Overridepublic void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {context = binding.getActivity();}@Overridepublic void onDetachedFromActivityForConfigChanges() {}@Overridepublic void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {}@Overridepublic void onDetachedFromActivity() {context = null;}
}

http://www.dtcms.com/wzjs/193472.html

相关文章:

  • 红酒公司网站建设微信群推广网站
  • 机械加工类网站怎么做怎么把网站排名优化
  • 视频号的网站链接热点新闻事件素材
  • 怎么给网站做开场动画seoul是啥意思
  • ui设计的基本流程图aso搜索优化
  • 福建省政府门户网站建设情况新闻稿发布平台
  • 电子商务是建网站苏州吴中区seo关键词优化排名
  • 国内做网站建设知名的公司网络营销推广处点
  • 广州有什么好玩的地方免费的重庆高端seo
  • 在电脑上打不开政府网站百度教育网站
  • 网站登录人数实时更新如何做十大最靠谱it培训机构
  • 做网站在阿里云买什么seo网络优化是做什么的
  • 网站有源代码如何做seo百度贴吧官网
  • ui界面设计分析网站关键词优化多少钱
  • 深圳福田疫情太原优化排名推广
  • 专题网站开发报价保定seo排名外包
  • oss挂载到wordpress百度seo关键词优化费用
  • 网站开发的趋势百度做广告推广怎么样
  • 定制礼品公司北京中文seo
  • 黔西做网站酒店推广渠道有哪些
  • 黑龙江省城市建设工程学校官方网站开发小程序
  • 卢龙网站建设百度一下网页首页
  • 最正规二手手表平台seo sem关键词优化
  • 嘉兴网站设计999 999缅甸在线今日新闻
  • 网站建设如何自学百度认证有什么用
  • 大连企业网站建设网站seo外包公司有哪些
  • 开个淘宝店做网站设计好吗百度大数据官网入口
  • 老哥们给个手机能看的2020南宁seo排名优化
  • 百度推广要企业自己做网站吗今日最新国内新闻
  • 中国城乡和住房建设部网站首页湛江今日头条