原生app调用uniapp集成原生sdk的页面,uniapp集成原生sdk怎么设置返回参数给原生app?


应大家的要求,我研究了一下相互传值操作
一、uni-app 跳转Android原生界面(Activity)并传值前端传值操作<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<input type="button" value="js start native Activity" onclick="jsCallNativeActivity()"/>
</body>
<script type="text/javascript">
function jsCallNativeActivity(){
//获取宿主上下文
var main = plus.android.runtimeMainActivity();
//通过反射获取Android的Intent对象
var Intent = plus.android.importClass("android.content.Intent");
//通过宿主上下文创建 intent
var intent = new Intent(main.getIntent());
//设置要开启的Activity包类路径
com.HBuilder.integrate.MainActivity换掉你自己的界面
intent.setClassName(main, "com.HBuilder.integrate.MainActivity");
//开启新的任务栈 (跨进程)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//向原生界面传值操作
intent.putExtra("uni_key","来自uniapp的值");
//开启新的界面
main.startActivity(intent);
}
</script>
</html>
做Android的都知道intent.putExtra(key,value)就是通过Intent进行不同组件之间传值操作,前端开发人员我建议直接封装成json传值,intent.putExtra(“uni_json_key”,"{key,“value1”}");Android端接收传值public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent mIntent = getIntent();
if (mIntent!=null){
//获取Intent,通过key获取对应的值
String uniValue = mIntent.getStringExtra("uni_key");
Toast.makeText(this, "uniValue="+uniValue, Toast.LENGTH_SHORT).show();
}
}
}
效果如下:二、uni-app 跳转Android原生界面(Activity)并传值,并返回uni-app时带返回值uni-app开启android 原生界面,并请求返回值
function jsCallNativeActivity(){
//获取宿主上下文
var main = plus.android.runtimeMainActivity();
//通过反射获取Android的Intent对象
var Intent = plus.android.importClass("android.content.Intent");
//通过宿主上下文创建 intent
var intent = new Intent(main.getIntent());
//设置要开启的Activity包类路径
com.HBuilder.integrate.MainActivity换掉你自己的界面
intent.setClassName(main, "com.HBuilder.integrate.MainActivity");
//开启新的任务栈 (跨进程)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//uni向android原生界面传值
intent.putExtra("uni_key","来自uniapp的值");
//请求码保证了,开始的新界面和返回的是同一个操作
var CODE_REQUEST=1000
//采用startActivityForResult开启新的界面,当界面关闭时可以处理返回结果, CODE_REQUEST请求码是唯一标识
main.startActivityForResult(intent,CODE_REQUEST);
//设置原生界面返回后的回调操作
main.onActivityResult = function(requestCode, resultCode, data) {
if (requestCode == CODE_REQUEST) {
alert(requestCode); //这个是正确的 1000
alert(resultCode);
//始终都是0
alert(data);
//弹出 undefined
}
}
}
Android端点击按钮,关闭原生界面,返回值
public void backValue(View view) {
Intent mIntent = new Intent();
mIntent.putExtra("Native_RESULT_Key", "来自原生界面的返回值");
setResult(Activity.RESULT_OK, mIntent);
finish();
}
上面一顿操作后,理论上应该是可以返回值的,但是实际上除了requestCode是正确的,其他的值都是错误的,为什么呢?我跟了安卓这边的官方demo源码,发现有bug,onActivityResult方法居然在开启新界面的时候就被调用,在返回的时候设置 setResult(Activity.RESULT_OK, mIntent);后onActivityResult压根就没有走,所以这样resultCode和data都没有被正常赋值,如下图log可以看到官方在这里挖了一个坑,多少人跳了进去,为什么他的生命周期方法会调用错乱呢?uni-app的demo是这么写的,用一个代理类去处理所有的事件操作只能看Android的官方源码也就是在我们开启原生的activity重新开始交互时,将在onResume()之前调用onActivityResult将上个界面的值返回,现在onActivityResult没有执行,说明uni-app在某些地方做了方法拦截,导致Android生命周期方法回调异常;所以这个问题需要uni-app官方处理,把Android的生命周期理顺我个人提出的解决方案就是采用EventBus去手动调用SDK_WebApp中的onActivityResult,具体如下1、app.gradle 依赖 implementation 'org.greenrobot:eventbus:3.0.0'2、创建DataSynEventpublic class DataSynEvent {
public int requestCode;
public int resultCode;
public Intent data;
public DataSynEvent(int requestCode, int resultCode, Intent data) {
this.requestCode = requestCode;
this.resultCode = resultCode;
this.data = data;
}
}
3、SDK_WebApp.java修改public class SDK_WebApp extends Activity implements IActivityDelegate {
private static final String TAG = "SDK_WebApp";
....
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
//注册EventBus
EventBus.getDefault().register(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
mEntryProxy.onStop(this);
//解绑EventBus
EventBus.getDefault().unregister(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult: " + data + ",requestCode=" + requestCode + ",resultCode=" + resultCode);
super.onActivityResult(requestCode, resultCode, data);
if (data!=null){
//第一次启动的时候调用这个方法data肯定为null.所以减少调用次数
mEntryProxy.onActivityExecute(this, SysEventType.onActivityResult, new Object[]{requestCode, resultCode, data});
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDataSynEvent(DataSynEvent event) {
Log.d(TAG, "onDataSynEvent: ");
//手动调用
onActivityResult(event.requestCode, event.resultCode, event.data);
}
}
4、修改原生界面的返回方法 public void backValue(View view) {
Intent data= new Intent();
data.putExtra("Native_RESULT_Key", "来自原生界面的返回值");
//用EventBus替换setResult(Activity.RESULT_OK,data);
EventBus.getDefault().post(new DataSynEvent(1000,Activity.RESULT_OK,data));
finish();
}
5、修改前端的接收方法
function jsCallNativeActivity(){
//获取宿主上下文
var main = plus.android.runtimeMainActivity();
//通过反射获取Android的Intent对象
var Intent = plus.android.importClass("android.content.Intent");
//通过宿主上下文创建 intent
var intent = new Intent(main.getIntent());
//设置要开启的Activity包类路径
com.HBuilder.integrate.MainActivity换掉你自己的界面
intent.setClassName(main, "com.HBuilder.integrate.MainActivity");
//uni向android原生界面传值
intent.putExtra("uni_key","来自uniapp的值");
//开启新的任务栈 (跨进程)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//请求码保证了,开始的新界面和返回的是同一个操作
var CODE_REQUEST=1000
//采用startActivityForResult开启新的界面,当界面关闭时可以处理返回结果, CODE_REQUEST请求码是唯一标识
main.startActivityForResult(intent,CODE_REQUEST);
//设置原生界面返回后的回调操作
main.onActivityResult = function(requestCode, resultCode, data) {
if (requestCode == CODE_REQUEST) {
alert(requestCode); //这个是正确的 1000
alert(resultCode);
//这个是正确的 -1
alert(data.getStringExtra("Native_RESULT_Key"));
//弹出 来自原生界面的返回值
}
}
}
6、上效果*看到官方论坛有人问main是啥东西,其实就是通过反射获取的宿主Activity的一个实例对象,也就是com.HBuilder.integrate.SDK_WebApp *2020年5月12日补充关于通信,uni-app官方在2020年四月底给出了相关api 宿主 App 向小程序发送事件Android 平台APIDCUniMPSDK.getInstance().sendUniMPEvent(event, data)
参数说明参数类型必填说明eventStringyes触发事件的eventdataString或者JSONyes事件携带的参数返回值类型说明booleantrue表示事件通知成功。false表示失败。可通过log查看。

我要回帖

更多关于 uniapp集成原生sdk 的文章

 

随机推荐