Android11对跨进程显式intent启动activity的限制

Android11对跨进程显式intent启动activity的限制

背景

今天项目中有用到跨进程启动Activity的知识,通过manifest发现,一个由其他进程调用的Activity配置了android.intent.action.MAIN这个action。所以自己想做个试验,这个action对跨进程启动有没有影响。

代码很简单,就是建了两个工程,第一个工程的textview添加响应事件跳转到第二个。

工程一:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun click(v: View) {
        val intent = Intent()
        val packageName = "com.example.secondapp"
        val className = "com.example.secondapp.SecondActivity"
        intent.component = ComponentName(packageName, className)
        startActivity(intent)
    }
}

xml就不列出来了,就是一个textview加一个点击事件。

工程二:

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

工程二的manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.secondapp">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".SecondActivity">
            <intent-filter>
                <action android:name="second.app"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

这里不讨论显式,隐式Intent调用的问题,这里直接说我遇到的现象。

本来是一个很正常的调用,之前也都用过,而且翻了几篇文章,也都是这么写并没有错。

但是,在跳转的时候,居然出现了错误。

Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.secondapp/com.example.secondapp.SecondActivity}; have you declared this activity in your AndroidManifest.xml?
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2065)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
        at android.app.Activity.startActivityForResult(Activity.java:5315)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
        at android.app.Activity.startActivityForResult(Activity.java:5273)
        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
        at android.app.Activity.startActivity(Activity.java:5659)
        at android.app.Activity.startActivity(Activity.java:5612)
        at com.example.firstapp.MainActivity.click(MainActivity.kt:21)
        at java.lang.reflect.Method.invoke(Native Method) 
        at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409) 
        at android.view.View.performClick(View.java:7448) 
        at android.view.View.performClickInternal(View.java:7425) 
        at android.view.View.access$3600(View.java:810) 
        at android.view.View$PerformClick.run(View.java:28296) 
        at android.os.Handler.handleCallback(Handler.java:938) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:223) 
        at android.app.ActivityThread.main(ActivityThread.java:7656) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

开玩笑!怎么可能没有注册manifest,activity是建app自动生成的好吗?

试了一下隐式的通过action启动,没问题。这就有点懵了啊!

带着错误,翻遍了国内国外所有的网站,没有找到自己想要的答案,最后无奈之下决定还是跟着走下android源码,看看到底是到哪里抛出了这个异常。

因为我的模拟器是最新版的android11,但是我的代码是android9的,在debug运行的时候代码行数对不上,无法跟踪。所以,我觉得模拟器降低版本,降低到于代码一样的android9。

经过一番下载,安装,装好了一个android9。0的模拟器
就在我把两个工程装好,准备调试一下的时候,发现点击工程一的textview居然跳转到了第二个工程的activity!!!

没想到浪费了一天时间的问题居然是因为系统问题,不知道android10 还是 android11 对这种通过包名和类名的调用给禁掉了?查阅官方文档也没找到相应的说明,或者哪里有我也没找到。。。

好吧,至于是10 还是 11,等有机会再试吧。


华丽的分割线


觉得还是要去官方文档找一找,看看有没有遗漏的地方,结果果然发现,原来android11对软件包的可见性,有新的规定了!

具体参照这里
Android 11 中的软件包可见性.

文章中说因为最小权限原则,所以这里不是所有的软件包都能在你的应用直接调用了,如果想调用的话,需要在manifest里配置queries标签,然后在里边放上package元素,写上你想要访问的应用的包名,这样才可以显式的跨进程调起Activity。

修改后的第一个工程的xml如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.firstapp">
    <queries>
        <package android:name="com.example.secondapp"/>
    </queries>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这里添加了

<queries>
        <package android:name="com.example.secondapp"/>
    </queries>

这个标签,表示我想要访问第二个工程的包名。

这样,就可以像之前一样通过包名和类名显式的调用我们第二个工程的Activity了,当然,这里隐式的调用是不受影响的。

除了通过包名访问需要配置,有一些情况的action和data等也需要配置,这里官方文档已经说的很清楚了,就不再举例一一说明了,大家自行查阅就好

Android 11 中的软件包可见性用例

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值