2019独角兽企业重金招聘Python工程师标准>>>

Activity

1. 创建Activity

1.1定义Class 继承Activity  重写onCreate(Bundle state)方法

2..1AndroidManifest.xml配置Activity   android:name

2. Activity跳转

//显式Intent

Intent intent = new Intent(this,SecondActivity.class);
startActivity(intent);Intent intent = new Intent();
intent.setClass(this,SecondActivity.class);
startActivity(intent);

//隐士Intent

String action = "intent.con.qu.custom";
Intent intent = new Intent(action );
startActivity(intent );

3. Activity传值

Activity之间通过Intent可以传递那些数据类型?

基本数据类型、对象(自定义)类型、集合类型()

3.1.基本数据类型

mIntent.putExtra(“info”,data);
Bundle bundle = new Bundle();
bundle.putStringExtra(“info”,data);
mIntent.putBundleExtra(“bundle”,bundle)

3.2.对象类型

Android 中自定义的对象序列化的问题有两个选择Parcelable、Serializable.

序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象.

选择原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类.
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC.
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下.尽管Serializable效率低点,也不提倡用,但在这种情况下,还是建议你用Serializable .

传递Serializable对象

//发送方
Intent intent = new Intent();
intent.setClass(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name",name);
bundle.putSerializable(“person”,person); //person必须实现Serializable接口
intent.putExtras(bundle);
//intent.putExtra("person", person);
startActivity(intent);
//接收方
Bundle bundle = getIntent().getExtras();
String name = bundle.getString("name");
Person person = (Person)bundle.getSerializableExtra("person");//获取Person对象

传递Parcelable对象

Parcelable接口是Android特定序列化接口,它比Serializable接口更有效,通常用于Binder和AIDL场景中.

Parcelable接口序列化的数据可以存储在Parcel中,继承Parcelable接口的类必须具有一个CREATOR的静态变量.

public class Mp3Info implements Parcelable {
private String id;private String mp3Name;private String mp3Size;private String lrcName;private String lrcSize;public Mp3Info() {super();}public Mp3Info(String id, String mp3Name, String mp3Size, String lrcName,String lrcSize) {super();this.id = id;this.mp3Name = mp3Name;this.mp3Size = mp3Size;this.lrcName = lrcName;this.lrcSize = lrcSize;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getMp3Name() {return mp3Name;}public void setMp3Name(String mp3Name) {this.mp3Name = mp3Name;}public String getMp3Size() {return mp3Size;}public void setMp3Size(String mp3Size) {this.mp3Size = mp3Size;}
public String getLrcName() {return lrcName;}public void setLrcName(String lrcName) {this.lrcName = lrcName;}public String getLrcSize() {return lrcSize;}public void setLrcSize(String lrcSize) {this.lrcSize = lrcSize;}public static final Parcelable.Creator<Mp3Info> CREATOR = new Creator<Mp3Info>() {@Overridepublic Mp3Info createFromParcel(Parcel source) {Mp3Info mp3Info = new Mp3Info();mp3Info.id = source.readString();mp3Info.mp3Name = source.readString();mp3Info.mp3Size = source.readString();mp3Info.lrcName = source.readString();mp3Info.lrcSize = source.readString();return mp3Info;}@Overridepublic Mp3Info[] newArray(int size) {return new Mp3Info[size];}};@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(id);dest.writeString(mp3Name);dest.writeString(mp3Size);dest.writeString(lrcName);dest.writeString(lrcSize);}@Overridepublic String toString() {return "Mp3Info [id=" + id + ", lrcName=" + lrcName + ", lrcSize="+ lrcSize + ", mp3Name=" + mp3Name + ", mp3Size=" + mp3Size+ "]";}
}

3.3.集合类型

ArrayList<Mp3Info> mp3List = new ArrayList<Mp3Info>();

4. Activity返回值

发送方:

startActivityForResult(intent,requestCode);onActivityResult(responseCode,requestCode,intent){}

接收方:

public void goFirst(View v){String str = et.getText().toString();Intent intent = new Intent();intent.putExtra(“back”,str+””)setResult(responseCode,intent);finish();
}

5. Activity生命周期

谈一谈Activity的生命周期?笔试  面试  3  7  分别

Activity的生命周期中启动,停止必然会调用的方法是?

启动  onResume

停止  onPause

了解Activity的生命周期的根本目的就是为了设计用户体验更加良好的应用。因为Activity就相当于MVC中的C层,是为了更好的向用户展现数据,并与之交互。

了解Activity的生命周期和各回调方法的触发时机,我们可以更好的在合适的地方向用户展现数据(因为每个应用每个Activity的作用不同,所以具体每个回调方法的最佳实践不好把握,但是只要遵循最基本的原则即可),保证数据的完整性和程序的良好运行。

除了我们自行启动(start)或者结束(finish)一个Activity,我们并不能直接控制一个Activity 的生命状态,我们只能通过实现Activity生命状态的表现——即回调方法来达到管理Activity生命周期的变化。

5.1.Activity生命周期

一个Activity可以基本上存在三种状态:

恢复

这项Activity是在屏幕前的,并有用户取得其焦点。(此状态,有时也简称为“运行”。)

暂停

另一个Activity在屏幕前,取得焦点,但原来的Activity仍然可见。也就是说,另一个Activity是这一个顶部可见,或者是部分透明的或不覆盖整个屏幕。暂停的Activity完全是存在的( Activity 对象保留在内存中,它维护所有状态和成员信息,并保持窗口管理器的联系),但在极低的内存的情况下,可以被系统终止。

停止

Activity完全被另一个Activity遮住了(现在Activity是在“background”)。停止Activity也仍然存在( Activity 对象保留在内存中,它保持状态和成员信息,但不和窗口管理器有关联)。然而,它已不再是对用户可见,其他地方需要内存时,它可以被系统终止。

如果一项Activity被暂停或停止,该系统可以从内存中删除它,要求它结束(调用它的finish() 方法),或者干脆杀死它的进程。Activity再次打开时(在被结束或被杀死),它必须创造所有的一切。

实现生命周期回调函数

当Activity按照如上所述在不同状态转进,出的时,是通过各种回调方法进行通知的。所有的回调方法是钩子,当的Activity状态变化时您可以覆盖他们来做适当的工作时。以下的Activity,包括基本生命周期的每一个方法:

public class ExampleActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// The activity is being created.}@Overrideprotected void onStart() {super.onStart();// The activity is about to become visible.}@Overrideprotected void onResume() {super.onResume();// The activity has become visible (it is now "resumed").}@Overrideprotected void onPause() {super.onPause();// Another activity is taking focus (this activity is about to be "paused").}@Overrideprotected void onStop() {super.onStop();// The activity is no longer visible (it is now "stopped")}@Overrideprotected void onDestroy() {super.onDestroy();// The activity is about to be destroyed.}
}

注意:在做任何事情之前,实现这些生命周期方法,必须始终调用父类的实现,如上面的例子所示。

综合来看,这些方法定义一个Activity的整个生命周期。通过实现这些方法,您可以监视Activity生命周期的三个嵌套循环:

Activity的整个存在周期发生在 OnCreate() 调用和 OnDestroy( 调用之间。Activity调用 OnCreate() 执行“全局”状态设置(如定义布局),并调用 OnDestroy( 释放所有剩余资源 。例如,如果Activity有一个线程在后台运行,从网络上下载数据,它可能会调用 OnCreate() 创建该线程 ,然后由 OnDestroy( 停止线程的 。

Activity的可见周期发生在 OnStart() 调用和 onStop() 调用之间。在这段时间内,用户可以看到屏幕上的Activity,并与它进行交互。例如,一个新的Activity时启动时,onStop()被调用,这时Activity不再可见。这两种方法之间,你可以维持运行Activity所需要的资源,提供给用户。例如,你可以在调用OnStart()

注册 BroadcastReceiver 监测影响你用户界面的变化,当用户可以不再看到你内容时,在 onStop() 时注销。在整个存在周期的Activity,Activity在可见和不可见的变化中,系统可能会多次调用OnStart() 和 OnStop () 。

Activity的前台周期发生在 onResume() 调用和 onPause() 调用之间。在这段时间内,该Activity显示在屏幕上,在所有其他Activity之前,具有用户输入焦点。一个Activity经常在前台后台之间转换,例如,当设备进入睡眠状态,或弹出一个对话框是 onPause()被称调用。因为这种状态转换,在这两种方法中的代码应该是相当轻量级的,以避免缓慢的转换,使用户等待。

图1说明了这些循环和Activity可能采取状态之间转换的路径。矩形代表可以实现在Activity状态转化之间要执行操作的回调方法。

1.启动onCreate()->onStart()->onResume()
2.按back键onPause()->onStop()->onDestroy()
再次启动:onCreate()->onStart()->onResume()
3.按home键onPause()->onStop() 再次启动时:onRestart()->onStart()->onResume()
4.切换到SecondActivity:FirstActivity.onPause()->FirstActivity.onStop()
再次启动时: FirstActivity.onRestart()->FirstActivity.onStart()->FirstActivity.onResume()
5.切换SecondActivity (FirstActivity.finish()):
FirstActivity.onPause()->FirstActivity.onStop()->FirstActivity.onDestroy()
再次启动时: FirstActivity.onCreate ()->FirstActivity.onStart()->FirstActivity.onResume()
6.切换到SecondActivity (SecondActivity主题为Dialog): FirstActivity.onPause()
再次启动时: FirstActivity.onRestart()->FirstActivity.onStart()->FirstActivity.onResume()
7.配置改变Activity生命周期
某些设备配置在运行时可以改变(如屏幕方向,键盘的可用性,和语言)。当这种变化发生时,Android重新运行Activity(系统调用的 onDestroy() ,然后立即调用的 onCreate()) 。这种行为旨在帮助您用您所提供的(如不同的屏幕方向和大小不同的布局)的替代资源进行应用程序自动重载,以适应新的配置。AndroidManifest.xml<activity
android:name=”…”
android:configChanges="keyboardHidden|orientation|screenSize"/>

5.2.Activity回调方法的作用

回调方法的作用,就是通知我们Activity生命周期的改变,然后我们可以处理这种改变,以便程序不会崩溃或者数据丢失等等,也就是拥有更好的用户体检,那么这么多回调方法里到底应该怎么做呢?

1、onCreate

最重要是在里面调用setContentView,还可以在里面初始化各控件、设置监听、并初始化一些全局的变量。

因为在Activity的一次生命周期中,onCreate方法只会执行一次。在Paused和Stopped状态下恢复或重启的下,这些控件、监听和全局变量也不会丢失。即便是内存不足,被回收了,再次Recreate的话,又是一次新的生命周期的开始,又会执行onCreate方法。

还可以在onCreate执行数据操作,比如从Cursor中检索数据等等,但是如果你每次进入这个Activity都可能需要更新数据,那么最好放在onStart里面。(这个需要根据实际情况来确定)

2、onDestory

确定某些资源是否没有被释放,做一些最终的清理工作,比如在这个Activity的onCreate中开启的某个线程,那么就要在onDestory中确定它是否结束了,如果没有,就结束它。

3、onStart和onRestart、onStop

Activity进入到Stopped状态之后,它极有可能被系统所回收,在某些极端情况下,系统可能是直接杀死应用程序的进程,而不是调用onDestory方法,所以我们需要在onStop方法中尽可能的释放那些用户暂时不需要使用的资源,防止内存泄露。

尽管onPause在onStop之前执行,但是onPause只适合做一些轻量级的操作,更多的耗时耗资源的操作还是要放在onStop里面,比如说对数据保存,需要用到的数据库操作。

因为从Stopped状态重启之后, onStart和onRestart方法都会被执行,所以我们要判断哪些操作分别要放在哪个方法里面 。因为可能在onStop方法里面释放了一些资源,那么我们必须要重启他们,这个时候这些重启的操作放在onStart方法里面就比较好(因为onCreate之后也需要开启这些资源)。那些因为Stopped之后引发的需要单独操作的代码,就可以放在onRestart里面。

4、onResume和onPause

onPause和onResume中做的操作,其实意义上和onStart和inStop差不多,只不过是要更轻量级的,因为onPause不能阻塞转变到下一个Activity。

比如:停止动画、取消broadcast receivers。当然相应的需要在onResume中重启或初始化等等。

有时候也需要在onPause判断用户是调用finish结束这个Activity,还是暂时离开,以便区分处理。这时候可以调用isFinishing()方法来判断。如果是用户finish这个Activity,那么返回为true,如果只是暂时离开或者被系统回收的话,就返回false。

6. Activity状态保存

Android里面保存数据状态有哪几种方式?

onPause()              用来持久化数据状态

onsavedInstanceState()   保存数据状态

一般来说, 调用Activity的onPause()和onStop()方法后的activity实例仍然存在于内存中, activity的所有信息和状态数据不会消失, 当activity重新回到前台之后, 所有的改变都会得到保留.

但是当系统内存不足时, 调用onPause()和onStop()方法后的activity可能会被系统摧毁, 此时内存中就不会存有该activity的实例对象了. 如果之后这个activity重新回到前台, 之前所作的改变就会消失. 为了避免此种情况的发生, 开发者可以覆写onSaveInstanceState()方法. onSaveInstanceState()方法接受一个Bundle类型的参数, 开发者可以将状态数据存储到这个Bundle对象中, 这样即使activity被系统摧毁, 当用户重新启动这个activity而调用它的onCreate()方法时, 上述的Bundle对象会作为实参传递给onCreate()方法, 开发者可以从Bundle对象中取出保存的数据, 然后利用这些数据将activity恢复到被摧毁之前的状态.

public class MainActivity extends Activity {public static final int SECOND_ACTIVITY = 0;private String temp;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 从savedInstanceState中恢复数据, 如果没有数据需要恢复savedInstanceState为nullif (savedInstanceState != null) {temp = savedInstanceState.getString("temp");System.out.println("onCreate: temp = " + temp);}}public void onResume() {super.onResume();temp = "xing";System.out.println("onResume: temp = " + temp);// 切换屏幕方向会导致activity的摧毁和重建 Ctrl+F12if (getRequestedOrientation() ==
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);System.out.println("屏幕切换");}}// 将数据保存到outState对象中, 该对象会在重建activity时传递给onCreate方法@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString("temp", temp);}
}

需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下BACK键退出activity时, 用户显然想要关闭这个activity, 此时是没有必要保存数据以供下次恢复的, 也就是onSaveInstanceState()方法不会被调用. 如果调用onSaveInstanceState()方法, 调用将发生在onPause()或onStop()方法之前.

onSaveInstanceState()方法的默认实现

如果开发者没有覆写onSaveInstanceState()方法, 此方法的默认实现会自动保存activity中的某些状态数据, 比如activity中各种UI控件的状态. android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法, 因此当activity被摧毁和重建时, 这些UI控件会自动保存和恢复状态数据. 比如EditText控件会自动保存和恢复输入的数据, 而CheckBox控件会自动保存和恢复选中状态. 开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可), 剩余的事情就可以自动完成了. 如果没有为控件指定ID, 则这个控件就不会进行自动的数据保存和恢复操作.

由上所述, 如果开发者需要覆写onSaveInstanceState()方法, 一般会在第一行代码中调用该方法的默认实现: super.onSaveInstanceState(outState).

是否需要覆写onSaveInstanceState()方法

既然该方法的默认实现可以自动的保存UI控件的状态数据, 那什么时候需要覆写该方法呢?

如果需要保存额外的数据时, 就需要覆写onSaveInstanceState()方法. 如需要保存类中成员变量的值(见上例).

onSaveInstanceState()方法适合保存什么数据

由于onSaveInstanceState()方法方法不一定会被调用, 因此不适合在该方法中保存持久化数据, 例如向数据库中插入记录等. 保存持久化数据的操作应该放在onPause()中. onSaveInstanceState()方法只适合保存瞬态数据, 比如UI控件的状态, 成员变量的值等.

引发activity摧毁和重建的其他情形

除了系统处于内存不足的原因会摧毁activity之外, 某些系统设置的改变也会导致activity的摧毁和重建. 例如改变屏幕方向(见上例), 改变设备语言设定, 键盘弹出等.

onSaveInstanceState保存数据

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><VideoViewandroid:id="@+id/videoView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>public class MainActivity extends Activity {private static final String TAG = "MainActivity";private VideoView videoView;private static final String VIDEO_PATH = Environment.getExternalStorageDirectory()+ File.separator+ "videoyueyu.3gp";@Overridepublic void onCreate(Bundle savedInstanceState) {//savedInstanceState就是保存的Activity一些状态super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.v(TAG, "onCreate");if (videoView == null) {videoView = (VideoView) this.findViewById(R.id.videoView);MediaController controller = new MediaController(this);videoView.setMediaController(controller);videoView.setVideoPath(VIDEO_PATH);videoView.requestFocus();}/*if (savedInstanceState != null&& savedInstanceState.getInt("currentPosition") != 0) {videoView.seekTo(savedInstanceState.getInt("currentPosition"));}*/videoView.start();}@Overrideprotected void onDestroy() {super.onDestroy();Log.v(TAG, "onDestroy");}@Overrideprotected void onPause() { //onPause()适合用于数据的持久化保存super.onPause();Log.v(TAG, "onPause");}@Overrideprotected void onRestart() {super.onRestart();Log.v(TAG, "onRestart");}@Overrideprotected void onResume() {super.onResume();Log.v(TAG, "onResume");}@Overrideprotected void onStart() {super.onStart();Log.v(TAG, "onStart");}@Overrideprotected void onStop() {super.onStop();Log.v(TAG, "onStop");}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);Log.v(TAG, "onRestoreInstanceState");if (savedInstanceState != null&& savedInstanceState.getInt("currentPosition") != 0) {videoView.seekTo(savedInstanceState.getInt("currentPosition"));}}@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);//onSaveInstanceState()只适合用于保存一些临时性的状态Log.v(TAG, "onSaveInstanceState");//横竖屏切换时保存播放状态outState.putInt("currentPosition", videoView.getCurrentPosition());}
}

onPause保存数据

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><EditTextandroid:id="@+id/editText"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="发送"/>
</LinearLayout>public class MainActivity extends AppCompatActivity {public static final String PREFS_NAME = "MyPrefsFile";private SharedPreferences settings;private EditText editText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);settings = getSharedPreferences(PREFS_NAME, 0);editText = (EditText)findViewById(R.id.editText);}@Overrideprotected void onPause() {super.onPause();String content = editText.getText().toString();SharedPreferences.Editor edit = settings.edit();edit.putString("content",content);edit.commit();}@Overrideprotected void onResume() {super.onResume();String content = settings.getString("content","");editText.setText(content);SharedPreferences.Editor edit = settings.edit();edit.clear();edit.commit();}
}

7. Activity栈(Task)

8. Activity加载模式

Activity launchMode是什么意思?

当启动一个Activity的时候,如何实例化这个Activity

取值有四个:

Standard        默认,每次都创建新的实例

SingleTop        Activity位于栈顶的时候不创建,其它位置同Standard

SingleTask       Actiivty在Task中已经被创建了,以后打开不再创建

SingleInstance   系统中只有一个实例

应用中的每一个Activity都是进行不同的事物处理。以邮件客户端为例,InboxActivity目的就是为了展示收件箱,这个Activity不建议创建成多个实例。而ComposeMailActivity则是用来撰写邮件,可以实例化多个此Activity对象。合理地设计Activity对象是否使用已有的实例还是多次创建,会使得交互设计更加良好,也能避免很多问题。至于想要达到前面的目标,就需要使用今天的Activity启动模式。

使用很简单,只需要在manifest中对应的Activity元素加入android:launchMode属性即可。如下述代码

<activityandroid:name=".SingleTaskActivity"android:launchMode="singleTask">
</activity>

介绍launchMode的四个取值

8.1. standard

这是launchMode的默认值,Activity不包含android:launchMode或者显示设置为standard的Activity就会使用这种模式。

一旦设置成这个值,每当有一次Intent请求,就会创建一个新的Activity实例。举个例子,如果有10个撰写邮件的Intent,那么就会创建10个ComposeMailActivity的实例来处理这些Intent。结果很明显,这种模式会创建某个Activity的多个实例。

8.2. singleTop

singleTop其实和standard几乎一样,使用singleTop的Activity也可以创建很多个实例。唯一不同的就是,如果调用的目标Activity已经位于调用者的Task的栈顶,则不创建新实例,而是使用当前的这个Activity实例,并调用这个实例的onNewIntent方法。

在singleTop这种模式下,我们需要处理应用这个模式的Activity的onCreate和onNewIntent两个方法,确保逻辑正常。

关于singleTop一个典型的使用场景就是搜索功能。假设有一个搜索框,每次搜索查询都会将我们引导至SearchActivity查看结果,为了更好的交互体验,我们在结果页顶部也放置这样的搜索框。

假设一下,SearchActivity启动模式为standard,那么每一个搜索都会创建一个新的SearchActivity实例,10次查询就是10个Activity。当我们想要退回到非SearchActivity,我们需要按返回键10次,这显然太不合理了。

但是如果我们使用singleTop的话,如果SearchActivity在栈顶,当有了新的查询时,不再重新创建SearchAc实例,而是使用当前的SearchActivity来更新结果。当我们需要返回到非SearchActivity只需要按一次返回键即可。使用了singleTop显然比之前要合理。

1.只有在调用者和目标Activity在同一Task中,并且目标Activity位于栈顶,才使用现有目标Activity实例,否则创建新的目标Activity实例。

2.如果是外部程序启动singleTop的Activity,在Android 5.0之前新创建的Activity会位于调用者的Task中,5.0及以后会放入新的Task中。

8.3. singleTask

singleTask这个模式和前面提到的standard和singleTop截然不同。使用singleTask启动模式的Activity在系统中只会存在一个实例。如果这个实例已经存在,intent就会通过onNewIntent传递到这个Activity。否则新的Activity实例被创建。

同一程序内

如果系统中不存在singleTask Activity的实例,那么就需要创建这个Activity的实例,并且将这个实例放入和调用者相同的Task中并位于栈顶。如果singleTask Activity实例已然存在,那么在Activity回退栈中,所有位于该Activity上面的Activity实例都将被销毁掉(销毁过程会调用Activity生命周期回调),这样使得singleTask Activity实例位于栈顶。与此同时,Intent会通过onNewIntent传递到这个SingleTask Activity实例。

在Google关于singleTask的文档有这样一段描述

The system creates a new task and instantiates the activity at the root of the new task.

意思为 系统会创建一个新的Task,并创建Activity实例放入这个新的Task的底部。

实现文档的描述,我们需要在设置launchMode为singleTask的同时,再加上taskAffinity属性即可。

跨应用之间

在跨应用Intent传递时,如果系统中不存在singleTaskActivity的实例,那么讲创建一个新的Task,然后创建SingleTask Activity的实例,将其放入新的Task中。

如果singleTask Activity所在的应用进程存在,但是singleTask Activity实例不存在,那么从别的应用启动这个Activity,新的Activity实例会被创建,并放入到所属进程所在的Task中,并位于栈顶位置。

该模式的使用场景多类似于邮件客户端的收件箱或者社交应用的时间线Activity。上述两种场景需要对应的Activity只保持一个实例即可,但是也要谨慎使用这种模式,因为它可以在用户未感知的情况下销毁掉其他Activity。

8.4. singleInstance

这个模式和singleTask差不多,因为他们在系统中都只有一份实例。唯一不同的就是存放singleInstance Activity实例的Task只能存放一个该模式的Activity实例。如果从singleInstance Activity实例启动另一个Activity,那么这个Activity实例会放入其他的Task中。同理,如果singleInstance Activity被别的Activity启动,它也会放入不同于调用者的Task中。

这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用。

9. Activity亲和性

什么是Activity的亲和性?

Activity的归属,当启动一个Activity,它应该在哪个Task中,Activity与Task的吸附关系。

以下情况会影响Activity与Task的关系:

1. <activity android:taskAffinity=”…” android: allowTaskReparenting =”…”/>

2.启动Activity,Intent.setFlags(Intent.FLAG_ACTIVIETY_NEW_TASK)

<activity android:taskAffinity=”…”/>

Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系。我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Task中度过自己的生命周期,这些Activity是从一而终的好榜样。

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。

一开始,创建的Activity都会在创建它的Task中,并且大部分都在这里度过了它的整个生命。然而有一些情况,创建的Activity会被分配其它的Task中去,有的甚至,本来在一个Task中,之后出现了转移。我们首先分析一下android文档给我们介绍的两种情况。

第一种情况。如果该Activity的allowTaskReparenting设置为true,它进入后台,当一个和它有相同affinity的Task进入前台时,它会重新宿主,进入到该前台的task中。

首先,我们启动app1,加载Activity1,然后按Home键,使该task(假设为task1)进入后台。然后启动app2,默认加载Activity2。本来应该是显示Activity2,但是我们却看到了Activity1。实际上Activity2也被加载了,只是Activity1重新宿主,所以看到了Activity1。

第二种情况。如果加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该Task中,如果不存在则重新创建Task。

<activity android:name=".SecondActivity"  android:taskAffinity="com.sina.cn"/>Intent intent = new Intent(FirstActivity.this,SecondActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);

转载于:https://my.oschina.net/quguangle/blog/789985

四大组件---Activity相关推荐

  1. 安卓开发.四大组件.activity.1

    安卓开发.四大组件.activity.1 转载于:https://www.cnblogs.com/motadou/p/3534056.html

  2. android的四大组件及使用场景,Android/四大组件/Activity.md · BoraxZYF/AndroidInterview - Gitee.com...

    ## 四大组件 ## Activity ### Activity 的四种启动模式及使用场景 - standard 标准模式,Activity 的默认启动模式.每次启动一个 Activity 时都会创建 ...

  3. 四大组件:Activity生命周期-Android12

    四大组件:Activity生命周期-Android12   Activity 类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分.在java编 ...

  4. Android四大组件---Activity

    1:前言 上一遍讲解了四大组件的广播----BroadcastReceiver,今天,我来解释一下四大组件最常用的activity. 2:概述 Activity 作为与用户交互的一个窗口,是使用非常频 ...

  5. Android 四大组件 -- Activity

    Android开发的四大组件分别是: 活动(activity),用于表现功能; 服务(service),后台运行服务,不提供界面呈现: 广播接受者(BroadcastReceive),勇于接收广播: ...

  6. Android 四大组件(Activity、Service、BroadCastReceiver、ContentProvider)

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一.了解四大基本组件 Activity ...

  7. Android之四大组件(Activity)

    Activity简述 Activity是Android应用中负责与用户交互的组件.在应用中创建自己的Activity需要继承Activity或者继承Activity的 子类. public class ...

  8. Android四大组件 - Activity知识点总结

    Activity Activity是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话.拍摄照片.发送电子邮件或查看地图等操作. 每个 Activity 都会获得一个用于绘制其用户界面的窗口. ...

  9. 四大组件 — Activity启动模式

    标准启动模式: standard:默认情况下所有的activity都是这种启动模式,典型的后进先出,即后开启的Activity视图浮在前视图的上层,当我们返回的视图的时候,先返回最上层. 单一顶部模式 ...

最新文章

  1. 500多页的机器学习入门笔记,下载超5万次,背后都有什么故事?
  2. Transformers2.0让你三行代码调用语言模型,兼容TF2.0和PyTorch
  3. apollo local 模式_Apollo 源码解析 —— 客户端配置 API(一)之一览
  4. vim 用次数做简单的算术运算(笔记)
  5. Py之openpyxl:openpyxl库的简介、安装、使用方法之详细攻略
  6. java静态方法声明_方法本地类中的Java最终静态声明
  7. android调用系统相册打开图片不显示,【报Bug】打开相册,不显示图片,选中图片后,app会崩溃...
  8. android 横向铺满,Android开发全程记录(八)——设置ImageView显示的图片铺满全屏(适应魅族等不常见屏幕比例)...
  9. 有人知道 I3C 吗?
  10. hsrp 切换_HSRP、VRRP、GLBP | 网络工程师之网关高可用、冗余
  11. ES6 Proxy和Reflect (上)
  12. django 1.8 官方文档翻译: 3-6-1 中间件概览
  13. 莫名其妙就发个手机!这家公司员工晒年终奖品:人手一部iPhone 11
  14. 典型环节的电路模拟MATLAB,典型环节的模拟及参数测试
  15. 每股收益具体怎么来的
  16. IOS简单的实现手机震动的提示
  17. 计数器的代码的原理分析
  18. 点集拓扑学的历史介绍
  19. windows10将耳机当作麦克风
  20. 神舟gx8cp5s1uefi的win10和ubuntu18.04双系统删除ubuntu

热门文章

  1. Python输出带颜色字体
  2. python中的参数
  3. Python Day15 jQuery
  4. x86_64的内存映射
  5. IOS开发学习笔记024-UIButton和UIImageView的区别
  6. Oracle命令--为数据文件缩容
  7. NetBeans与myeclipse区别
  8. 利用CRT库函数检查内存泄漏
  9. Json(四):Json增、删、改
  10. 什么是气泡图?怎样用Python绘制?有什么用?终于有人讲明白了