android 不用startactivity 怎么开启activity的方法

android 不用startactivity 怎么开启activity的方法,第1张

启动其他APK的Activity方法

有两个app,分别叫做App1和App2。

App1包含两个Activity,分别叫做App1_A和App1_B其中App1_A是入口Activity

也就是App1_A设置intent-filter,action为<action android:name="androidintentactionMAIN" />

App2只有一个Activity,叫做App2_A。

现在在App2_A中通过startActivity启动App1_A是没问题的但是启动App1_B的时候报了fc错误。

logcat如下:

08-03 02:23:44119: WARN/ActivityManager(64): Permission denied: checkComponentPermission() reqUid=10030

08-03 02:23:44119: WARN/ActivityManager(64): Permission Denial: starting Intent { act=androidintentactionVIEW cmp=comhello/activity2 } from ProcessRecord{407c8bc8 665:comfileExplorer/10032} (pid=665, uid=10032) requires null

用法如下:

Intent intent = new Intent();

ComponentName componentName = new ComponentName("comhello","comhelloApp1_A");//这个没问题

//ComponentName componentName = new ComponentName("comhello","comhelloApp1_B");//这个报错

intentsetComponent(componentName);

startActivity(intent);

解决方法:

(1)

通过隐式intent调用方法实现,需要在被调用的activity的manifest文件中添加

<intent-filter>

<action android:name="comexampleprojectSHOW_ACTIVITY" />

<category android:name="androidintentcategoryDEFAULT" />

</intent-filter>

在StartActivity(it)之前,设定该intent对应的action(comexampleprojectSHOW_ACTIVITY)

Intent intent = new Intent();

intentsetAction(action);

intentaddFlags(IntentFLAG_ACTIVITY_NEW_TASK);

contextstartActivity(intent);推荐使用

利用setAction方法启动Activity还有一个好处就是不需要知道包名和Activity类名,只需要知道action就可以隐式的启动activity

(2)

即使直接指定了目标activity的ComponentName,跨应用的activity调用也要至少给目标activity指定一个带action的filter。如:

<intent-filter>

<action android:name="" />

</intent-filter>

action name为空即可。

(3)给被调用的Activity增加一个带action的filter,如下:

<intent-filter>

<action android:name="comsdmcottplayeruercenter" />

</intent-filter>

然后可以通过隐式Intent来调用,而不用使用intentsetComponent方法,如下就OK了(但是经过验证,这种方法只是对APK的入口activity有用,对普通的没用,和上面的问题一样无法解决:启动其他APK的非入口activity)

Intent i = new Intent("comsdmcottplayeruercenter");

isetFlags(IntentFLAG_ACTIVITY_NEW_TASK);

thisstartActivity(intent);

异常处理:

Caused by: androidutilAndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag Is this really what you want

Context中有一个startActivity方法,Activity继承自Context,重载了startActivity方法。

如果使用 Activity的startActivity方法,不会有任何限制,

而如果使用Context的startActivity方法的话,就需要开启一个新 的task,遇到上面那个异常的,都是因为使用了Context的startActivity方法。

解决办法是,加一个flag。intentaddFlags(IntentFLAG_ACTIVITY_NEW_TASK)

Intent intent = new Intent();

intentsetClass(mContext, VideoPlayerclass);

intentaddFlags(IntentFLAG_ACTIVITY_NEW_TASK);

mContextstartActivity(intent);

楼主要的应该是触摸dialog 以外的部分,dialog自动关闭吧?

void setCanceledOnTouchOutside(boolean cancel), 置成truexml的配置文件中也有对应的属性,你自己查一下

1、设置Intent

Intent intent = new Intent(当前Activitythis, 要打开的Activityclass);

2、通过startActivity打开activity

startActivity(intent);//打开新的activity

[1] 一个 APP 从启动到主页面显示经历了哪些过程

[2] startActivity 启动过程分析 - Gityuan

[3] 译Android Application 启动流程分析

[4] 凯子哥带你学 FrameworkActivity 启动过程全解析

[5] Android Framework 之 Activity 启动流程(一)

[6] 任务和返回堆栈

1 从 Activity 本地调用startActivity()--> Activity#startActivityForResult()

2 Instrumentation #execStartActivity:Instrumentation类相当于一个管家,它的职责是管理各个应用程序和系统的交互,Activity都有此对象的实际引用,可以通过它监测系统与应用程序之间的所有交互。

3 ActivityManagerProxy #startActivity():发起了一次跨进程调用,ActivityManagerService是ActivityManagerNative的具体实现。

4 ActivityStarter ():主要负责处理Activity的Intent和Flags, 还有关联相关的Stack和TaskRecord。

ActivityStackstartActivityMayWait():获取Activity的启动信息,包括ResolveInfo和ActivityInfo,以及获取CallingPid和CallingUid;

ActivityStackstartActivityLocked():创建一个ActivityRecord;

ActivityStackstartActivityUnchecked():设置TaskRecord, 完成后执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked方法

5 ActivityStackSupervisor 和 ActivityStack :这里会判断进程是否存在和一些生命周期的方法

ActivityStackSupervisor#resumeFocusedStackTopActivityLocked()

  --> ActivityStackSupervisor#resumeTopActivityUncheckedLocked():

    --> ActivityStack#resumeTopActivityInnerLocked()

      --> ActivityStackSupervisor#startSpecificActivityLocked()

6: ApplicationThread :IApplicationThread的直接实现,发起了一次跨进程调用

7: ActivityThread :会调用sendMessage,最后调用到mHsendMessage(msg);

8: ActivityThread # performLaunchActivity ():会收集要启动的Activity的相关信息,主要是package和component信息,然后通过ClassLoader将要启动的Activity类加载出来。最后调用mInstrumentationcallActivityOnCreate()

9: Activity # performStart ():Activity的生命周期方法是通过Instrumentation类调用callActivityOnXXX方法最终调用Activity的onCreate等方法,调用时机为ActivityThread#performLaunchActivitiy()方法中。

一 应用程序的MainActivity通过Binder进程间通信机制通知ActivityManagerService,它要启动一个新的Activity;

二 ActivityManagerService通过Binder进程间通信机制通知MainActivity进入Paused状态;

三 MainActivity通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就准备要在MainActivity所在的进程和任务中启动新的Activity了;

四 ActivityManagerService通过Binder进程间通信机制通知MainActivity所在的ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动 *** 作了。

Instrumentation : 监控应用与系统相关的交互行为。

AMS :组件管理调度中心,什么都不干,但是什么都管。

ActivityStarter :处理Activity什么时候启动,怎么样启动相关问题,也就是处理Intent与Flag相关问题,平时提到的启动模式都可以在这里找到实现。

ActivityStackSupervisior :这个类的作用你从它的名字就可以看出来,它用来管理Stack和Task。

ActivityStack :用来管理栈里的Activity。

ActivityThread :最终干活的人,是ActivityThread的内部类,Activity、Service、BroadcastReceiver的启动、切换、调度等各种 *** 作都在这个类里完成。

目录

activity的简单介绍就不写了,作为最常用的四大组件之一,肯定都很熟悉其基本用法了。

首先,是都很熟悉的一张图,即官方介绍的Activity生命周期图

情景:打开某个应用的的FirstActivity调用方法如下:

由于之前已经很熟悉了,这里就简单贴一些图。

按下返回键:

重新打开并按下home键:

再重新打开:

在其中打开一个DialogActivity(SecondActivity)

按下返回:

修改SecondAcitvity为普通Activity,依旧是上述 *** 作:

这里强调一下 onSaveInstanceState(Bundle outState) 方法的调用时机:

当Activity有可能被系统杀掉时调用,注意,一定是被系统杀掉,自己调用finish是不行的。

测试如下:FirstActivity启动SecondActivity:

一个App会包含很多个Activity,多个Activity之间通过intent进行跳转,那么原始的Activity就是使用栈这个数据结构来保存的。

Task

A task is a collection of activities that users interact with when performing a certain job The activities are arranged in a stack (the back stack ), in the order in which each activity is opened

即若干个Activity的集合的栈表示一个Task。

当App启动时如果不存在当前App的任务栈就会自动创建一个,默认情况下一个App中的所有Activity都是放在一个Task中的,但是如果指定了特殊的启动模式,那么就会出现同一个App的Activity出现在不同的任务栈中的情况,即会有任务栈中包含来自于不同App的Activity。

标准模式,在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例,覆盖在原有的Activity上,原有的Activity入栈。

测试如下:在FirstActivity中启动FirstActivity:

当只有一个FirstActivity时堆栈情况:

此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。

测试,设置FirstActivity为此启动模式,多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况:

(其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity)

大意就是:

对于使用singleTop启动或IntentFLAG_ACTIVITY_SINGLE_TOP启动的Activity,当该Activity被重复启动(注意一定是re-launched,第一次启动时不会调用)时就会调用此方法。

且调用此方法之前会先暂停Activity也就是先调用onPause方法。

而且,即使是在新的调用产生后此方法被调用,但是通过getIntent方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。

方法参数就是新传递的Intent

1如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。

测试:SecondActivity启动模式设为singleTask,启动三个Activity:

这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。

测试:SecondActivity启动模式设为singleInstance

结果:

显然,启动了两次ThirdActivity任务栈中就有两个实例,而SecondActivity在另外一个任务栈中,且只有一个。

在使用Intent启动一个Activity时可以设置启动该Activity的启动模式:

这个属性有很多,大致列出几个:

每个启动的Activity都在一个新的任务栈中

singleTop

singleTask

用此种方式启动的Activity,在它启动了其他Activity后,会自动finish

官方文档介绍如下:

这样看来的话,通俗易懂的讲,就是给每一个任务栈起个名,给每个Activity也起个名,在Activity以singleTask模式启动时,就检查有没有跟此Activity的名相同的任务栈,有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。

测试:在App1中设置SecondActivity的taskAffinity为“gsqtest”,App2中的ActivityX的taskAffinity也设为“gsqtest”

任务栈信息如下:

结果很显然了。

测试:在上述基础上,在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下:

这样就没问题了,ActivityY在一个新的任务栈中,名称为包名。

这时从ActivityY跳转到SecondActivity,那应该是gsqtest任务栈只有SecondActivity,ActivityX已经没有了。因为其启动模式是singleTask,在启动它时发现已经有一个实例存在,就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。

还有一点需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器,故在FirstActivity跳转到SecondActivity时,按下home键,再点开App1,回到的是FirstActivity。

大致就先写这么多吧,好像有点长,废话有点多,估计也有错别字,不要太在意~~~

以上就是关于android 不用startactivity 怎么开启activity的方法全部的内容,包括:android 不用startactivity 怎么开启activity的方法、Android 怎么在Activity中启动另一应用程序的方法,无需得到类名、android 如何打开一个新的activity等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10171262.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-06
下一篇 2023-05-06

发表评论

登录后才能评论

评论列表(0条)

保存