从网页点击某个按钮跳转到APP之后,正常使用,可是当你打开手机后台应用时却发现APP竟然在浏览器里,如下图
我擦,这怎么能行呢!,其实用户用起来也没啥感觉,就是在APP中使用的,只不过两者合体了,这样如果你想杀死浏览器或者APP时就尴尬了,体验不太好,
再说解决办法之前先说一下如何通过浏览器打开APP
1.在手机清单文件中,在你想要打开的Activity配置里添加如下:
<!-- 注册scheme -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!-- BROWSABLE指定该Activity能被浏览器安全调用 -->
<category android:name="android.intent.category.BROWSABLE" />
<!-- 声明自定义scheme,类似于http, https -->
<data android:scheme="我是Scheme名字" />
</intent-filter>
这样在网页调用相关语句就可以唤醒该APP的此Activity了
网页部分俺也不太懂,就百度了一下,大体是通过JS点击语句中加这么一句
window.location.href="palmos://";//打开某手机上的某个app应用
"palmos://"是什么呢?它是在客户端设置一个URL Scheme名字
既然能跳转到 APP 肯定也能传一下参数咯,在相关的Activity中通过
getIntent().getData()
就能获取到网页传过来的一些参数,此时就可以进行一些判断逻辑的处理了
上面介绍的有点水,大体就是那个意思。。。。
接下来说一下浏览器嵌套APP的解决办法,亲测有效!
既然前台使用没有异常,后台浏览器和APP位置异常,可以考虑下是否是启动模式问题,当点击按钮之后应用异常可能是启动模式导致实例在站内的位置等因素导致的,标准模式和栈顶模式下都还会出现以上问题,栈内复用的时候嵌套问题解决了,但是APP在启动时,你点击浏览器跳转不会跳到对应界面,是的没错!单例模式解决了这个问题,目前没有发现异常
都说到启动模式了,这里简单说一下用法吧,具体场景和区别不多说了
在清单文件中Activity声明的地方进行注册,前面的截图中也有哦
标准模式 android:launchMode="standard"
栈内复用android:launchMode="singleTask"
栈顶复用android:launchMode="singleTop"
单例模式android:launchMode="singleInstance"
这里完善一下!因为昨天写完之后自测不充分,今天测试提出了以下问题:
1.通过以上方式确实使APP与浏览器分离了,但是由于启动模式加持,导致每次APP进入后台之后,点击图标再次进入时都会重启APP,这样肯定是不行的。
2.APP在运行时如果点击浏览器要打开APP同样也会重新启动APP,这样会使原有数据或多或少造成改变,也是不可取得。
思路:通过网上查找关于APP跳转的 scheme 相关,发现有的大佬也建议将启动模式改为复用模式,这样确实能解决APP重启问题,但是APP如果运行状态或者后台状态时,跳转之后是获取不到 getIntent() 数据的,会直接使用原有实例,效果不太理想
解决办法:假如说你想要浏览器打开之后的界面是启动页或者首页,不要直接在相应的清单文件中去注册scheme,这里建议不管是微信跳转还是浏览器跳转都不要直接去与对应界面进行交接,首先使用一个容器去当作跳转踏板。
比如说我的需求是浏览器点击之后跳转到我的界面,不要直接在我的Activity中去注册,首先建一个 Activity 去当作踏板,在踏板Activity的清单文件中进行注册,这样受影响的仅仅是踏板Activity。然后在踏板界面中进行getIntent() 逻辑操作,比如跳转到我的界面。跳转之后及时 finish() 掉踏板Activity ,这样踏板Activity还是使用单例模式启动。每次浏览器跳转之后都到踏板界面,因为踏板界面使用的是单例模式,APP与浏览器会分开,踏板界面完成任务后及时销毁,APP正常继续执行,这时就算APP回到后台还是点击图标都与踏板无关
以上就是实际思路,下面抛出踏板相关代码以供参考:
踏板Activity,这里没有建xml布局文件,仅仅继承一个Activity,因为他只是一个过客!
/**
* 浏览器跳转的回调界面
* */
public class NjscNetworkActivity extends Activity {
public static boolean pdtId = false;//是否是网页跳转过来的
protected void onCreate(Bundle savedInstanceState) {
this.setTheme(16973839);
super.onCreate(savedInstanceState);
if (getIntent() != null && getIntent().getData() != null ) {
//包含该字段说明浏览器跳转过来,进行我想要的操作
if (getIntent().getData().toString().contains(qsPub.NJSCSD_LLQ_TZ_TG)) {
//跳到我的界面
this.startActivity(new Intent(NjscNetworkActivity.this, NjscNetworkActivity.class));
pdtId = true;
}else {
pdtId = false;
}
}else {
pdtId = false;
}
this.finish();
}
}
踏板清单文件,注意这里的启动模式声明和scheme注册,经调试发现,用踏板形式打开之后,不在清单文件中声明启动模式,app同样没有嵌套在浏览器里,这里建议还是声明一下,防止个别机型同样会出现
<!--浏览器跳转页-->
<activity
android:name="com.newtzt.activity.NjscNetworkActivity"
android:configChanges="orientation|keyboardHidden|fontScale|screenSize"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:theme="@style/tztzz_HeadPage_Theme.tztZZWhite">
<!-- 注册scheme -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!-- BROWSABLE指定该Activity能被浏览器安全调用 -->
<category android:name="android.intent.category.BROWSABLE" />
<!-- 声明自定义scheme,类似于http, https -->
<data android:scheme="com.com.com" />
</intent-filter>
</activity>
以上就是浏览器打开APP之后,APP嵌套在浏览器里的解决思路以及遇到的问题,如果BUG继续完善,唉~