uniapp主屏继承WebappActivity并实现跳转原生页面
背景
项目需要,想在uniapp页面内通过一个点击事件跳转到安卓原生页面。百度没找到解决办法。
分析
- 要实现跳转原生必须要得到Activity的控制权,就是要继承框架二次封装的Activity基类。
- 有了Activity控制权后需要在uniapp通过js拿到Activity的实例。
- 有了实例后再通过自定义方法跳转Activity。
资料
- 自定义Activity继承
PandoraEntryActivity
- 这里还有一个细节需要手动处理:uniapp的启动流程是先进入
PandoraEntry
,再到PandoraEntryActivity
的,这里PandoraEntry
跳转的页面默认是PandoraEntryActivity
,所以我们需要自定义一个入口让他跳转到我们自己的MainActivity
。 - 自定义的
Entry
入口类中需要传入一个__start_from_to_class__
的intent参数才能让PandoraEntry
跳转到自定义的主活动页。 - 不建议在自定义的
Entry
类中直接跳转MainActivity
,因为PandoraEntry
可能有一些初始化动作。
- 这里还有一个细节需要手动处理:uniapp的启动流程是先进入
plus.android.runtimeMainActivity()
可以直接拿到当前的Activity实例,uniapp页面中一般都只在主活动中,很少跳转到其他活动。- 安卓原生通过
Intent
可以实现页面跳转。
完整代码
// 新的入口
package com.xxx.xx;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import io.dcloud.PandoraEntry;
public class Entry extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = this.getIntent();
// 自定义的入口
intent.putExtra("__start_from_to_class__", MainActivity.class.getName());
// 进入uniapp自带入口
intent.setClass(this, PandoraEntry.class);
this.startActivity(intent);
}
}
// 自定义MainActivity,以后uniapp就在这个页面渲染
package com.xxx.xx;
import io.dcloud.PandoraEntryActivity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends PandoraEntryActivity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
}
/**
* 跳转原生页面
*/
public void testActivity() {
Intent intent = new Intent(MainActivity.this, TestActivity.class);
startActivity(intent);
}
}
manifest也要修改,相关保密字串用xxx代替:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xxx.xx">
<uses-sdk tools:overrideLibrary="com.bun.miitmdid" />
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.xxx">
<meta-data
android:name="dcloud_appkey"
android:value="xxx" />
<!-- 新的Activity -->
<activity android:name=".TestActivity" />
<!-- 原来的 io.dcloud.PandoraEntry -->
<activity
android:name=".Entry"
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
android:hardwareAccelerated="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="user"
android:theme="@style/TranslucentTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--删除原来 io.dcloud.PandoraEntry 的intent-filter -->
<activity android:name="io.dcloud.PandoraEntry"
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:screenOrientation="user"
android:theme="@style/TranslucentTheme"
android:windowSoftInputMode="adjustResize" />
<!-- 原来的io.dcloud.PandoraEntryActivity -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale|keyboard|smallestScreenSize|screenLayout|screenSize"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:permission="com.miui.securitycenter.permission.AppPermissionsEditor"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<action android:name="android.intent.action.VIEW" />
<data android:scheme="xxx" />
</intent-filter>
</activity>
<provider
android:name="io.dcloud.common.util.DCloud_FileProvider"
android:authorities="com.xxx.xx.dc.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/dcloud_file_provider" />
</provider>
</application>
</manifest>
uniapp中:
let bundle = plus.android.runtimeMainActivity();
bundle.testActivity();
踩坑
如果需要调试原生页面的话,肯定需要直接运行到手机的,但是每次直接运行打开都会提示
未配置appkey或配置错误
导致进不了应用。这个问题其实是因为Android Studio直接运行的时候会以debug运行,就是免签名运行,这样会使uniapp框架识别不到我们配置的appid,所以会出现上述问题。解决办法很简单:// gradle中配置 signingConfigs { debug { // 填你的签名文件路径 storeFile file('xx/xx/xx.jks') storePassword 'xxx' keyAlias 'xxx' keyPassword 'xxx' v1SigningEnabled true v2SigningEnabled true } } // 或者Android Studio中设置: // File->Project Stucture->Modules->Signing Configs // 选debug按提示填资料即可 // 设置完后记得gradle补充两个参数v1SigningEnabled、v2SigningEnabled // 又或者在最左侧工具栏里选Build Variants,在Active Build Variant中选择release,让调试也按发布版本的配置运行。这个方法可能在运行的时候会报错,暂时不知道什么原因。 // 配置好后直接运行就可以了
不要尝试通过配置uniapp框架来跳过appkey验证,我没有发现更好的uniapp配置办法。
2022-02-09后续,单独继承跳转不可靠,在退出应用时会回到第一屏,这时候的第一屏是无ui状态,会黑屏,需要另寻方案。
uniapp主屏继承WebappActivity并实现跳转原生页面
http://blog.icy8.cn/posts/23303/