方式一:AndroidMenifest中设置:
android:name=".TestActivity" Activity类名
android:allowTaskReparenting="true" 允许应用外的请求启动此Activity
android:configChanges="screenSize" 设置屏幕的一些参数,例如取消横竖屏切换
android:launchMode="singleTask" Activity启动模式
android:taskAffinity="com.abc.task" /> 设置Activity所属栈名
方式二:代码中进行设置:
Intent intent = new Intent();
intent.setClass(this,TestActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Activity的任务栈
按照是否可见分:前台任务栈、后台任务栈
检测Activity任务栈
出现界面跳转异常时,可以导出activity任务栈。
adb shell dumpsys activity activities >e:1
结果如下:
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #1: 前台任务栈
。。。。
Running activities (most recent first):
TaskRecord{b020cad #2036 A=com.zxcn.imai.smart U=0 StackId=1 sz=5}
Run #6: ActivityRecord{fee230c u0 com.zxcn.imai.smart/.activity.ecg.EcgResultActivity t2036}
Run #5: ActivityRecord{a0938c8 u0 com.zxcn.imai.smart/.activity.ecg.EcgMainActivity t2036}
Run #4: ActivityRecord{8dfaaa2 u0 com.zxcn.imai.smart/.activity.common.FunctionChoseActivity t2036}
Run #3: ActivityRecord{f8265ec u0 com.zxcn.imai.smart/.activity.common.RoleChoseActivity t2036}
Run #2: ActivityRecord{a8a4be2 u0 com.zxcn.imai.smart/.activity.common.MainActivity t2036}
TaskRecord{feb4ae4 #1911 A=com.huawei.appmarket U=0 StackId=1 sz=2}
Run #1: ActivityRecord{7447718 u0 com.huawei.appmarket/.service.search.view.SearchActivity t1911}
Run #0: ActivityRecord{5ed9d62 u0 com.huawei.appmarket/.MarketActivity t1911}
mResumedActivity: ActivityRecord{fee230c u0 com.zxcn.imai.smart/.activity.ecg.EcgResultActivity t2036}
mLastPausedActivity: ActivityRecord{a0938c8 u0 com.zxcn.imai.smart/.activity.ecg.EcgMainActivity t2036}
Stack #0: 后台任务栈
。。。
Running activities (most recent first):
TaskRecord{823308a #1857 A=com.huawei.android.launcher U=0 StackId=0 sz=1}
Run #1: ActivityRecord{481e6fb u0 com.huawei.android.launcher/.unihome.UniHomeLauncher t1857}
TaskRecord{5433a2b #1910 A=com.android.systemui U=0 StackId=0 sz=1}
Run #0: ActivityRecord{19b0e88 u0 com.android.systemui/.recents.RecentsActivity t1910}
四种启动模式
表现:
前台任务栈 :TaskRecord是否增加,TaskRecord的出栈入栈
standard是Activity默认的启动模式,在不指定Activity启动模式的情况下,所有Activity使用的都是standard模式。
在standard模式下,每当启动一个新的Activity,它就会进入前台任务栈,并处于栈顶的位置,对于使用standard模式的Activity,系统不会判断该Activity在栈中是否存在,每次启动都会创建一个新的实例。下图所示的是standard启动模式下Activity在栈中的存放情况:
从图中我们可以看出,在standard启动模式下Activity01最先进栈,其次是Activity02,最后是Activity03;出栈时,Activity03最先出栈,其次是Activity02,最后是Activity01,满足“先进后出”的原则。
singleTop模式与standard类似,不同的是,当启动的Activity已经位于栈顶时,则直接使用它不创建新的实例。如果启动的Activity没有位于栈顶时,则创建一个新的实例位于栈顶。下图所示的是singleTop模式下Activity在栈中的存放情况:
从图中我们可以看出,当前栈顶中的元素是Activity03,如果再次启动的界面还是Activity03,则复用当前栈顶的Activity实例,如果再次启动的界面没有位于栈顶,则会重新创建一个实例。
如果希望Activity在整个应用程序中只存在一个实例,可以使用singleTask模式,当Activity的启动模式指定为 singleTask,每次启动该Activity时,系统首先会检查栈中是否存在该Activity的实例,如果发现已经存在则直接使用该实例,并将当前Activity之上的所有Activity出栈,如果没有发现则创建一个新的实例。下图所示的是singleTask模式下的Activity在栈中的存放情况:
从图中可以看出,当再次启动Activity02时,并没有创建新的实例,而是将Activity03实例移除,复用Activity02 实例,这就是singleTask模式,让某个Activity在当前栈中只存在一个实例。
在程序开发过程中,如果需要Activity在整个系统中都只有一个实例,这时就需要用到singleInstance模式。不同于以上介绍的三种模式,指定为singleInstance模式的Activity会启动一个新的任务栈来管理这个Activity。
singleInstance模式加载Activity时,无论从哪个任务栈中启动该Activity,只会创建一个Activity实例,并且会使用一个全新的任务栈来装载该Activity实例。采用这种模式启动Activity会费为一下两种情况:
第一种:如果要启动的Activity不存在,系统会创建一个新的任务栈,在创建该Activity的实例,并把该Activity加入栈顶,如下图所示:
第二种::如果要启动的Activity已经存在,无论位于哪个应用程序或者哪个任务栈中,系统都会把该Activity所在的任务栈转到前台,从而使该Activity显示出来。
至此,Activity的四种启动模式已经讲解完成,在实际开发中,需要根据实际情况来选择合适的启动模式。
以下是ExampleActivity分别跳转到Activity21,Activity22,Activity22,Activity24的前台任务栈的情况:
Stack #1:
Running activities (most recent first):
TaskRecord{15e9dd7 #2552 A=com.zxcn.test U=0 StackId=1 sz=2}
Run #1: ActivityRecord{f6cf2a8 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.ExampleActivity t2552}
Run #0: ActivityRecord{4aae6c4 u0 com.zxcn.test/com.hy.app.activity.MainActivity t2552}
Running activities (most recent first):
TaskRecord{15e9dd7 #2552 A=com.zxcn.test U=0 StackId=1 sz=3}
Run #2: ActivityRecord{dc87d76 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.Activity21 t2552}
Run #1: ActivityRecord{f6cf2a8 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.ExampleActivity t2552}
Run #0: ActivityRecord{4aae6c4 u0 com.zxcn.test/com.hy.app.activity.MainActivity t2552}
Running activities (most recent first):
TaskRecord{e4e8a8b #2553 A=com.zxcn.test U=0 StackId=1 sz=1}
Run #2: ActivityRecord{8298768 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.Activity22 t2553}
TaskRecord{15e9dd7 #2552 A=com.zxcn.test U=0 StackId=1 sz=2}
Run #1: ActivityRecord{f6cf2a8 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.ExampleActivity t2552}
Run #0: ActivityRecord{4aae6c4 u0 com.zxcn.test/com.hy.app.activity.MainActivity t2552}
Running activities (most recent first):
TaskRecord{15e9dd7 #2552 A=com.zxcn.test U=0 StackId=1 sz=3}
Run #2: ActivityRecord{d33eed6 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.Activity23 t2552}
Run #1: ActivityRecord{f6cf2a8 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.ExampleActivity t2552}
Run #0: ActivityRecord{4aae6c4 u0 com.zxcn.test/com.hy.app.activity.MainActivity t2552}
Running activities (most recent first):
TaskRecord{15e9dd7 #2552 A=com.zxcn.test U=0 StackId=1 sz=3}
Run #2: ActivityRecord{349ca74 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.Activity24 t2552}
Run #1: ActivityRecord{f6cf2a8 u0 com.zxcn.test/com.hy.base.androidbase.component.activity.ExampleActivity t2552}
Run #0: ActivityRecord{4aae6c4 u0 com.zxcn.test/com.hy.app.activity.MainActivity t2552}
package com.hy.base.androidbase.component.activity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.hy.app.base1.BaseActivity;
import com.hy.app.component.R;
public class ExampleActivity extends BaseActivity {
int code = 1;
/**
* **********************************************************************
* 典型情况下的生命周期
* **********************************************************************
* */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
Log.v("060" ,"ExampleActivity onCreate");
}
@Override
protected void onStart() {
super.onStart();
Log.v("060" ,"ExampleActivity onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.v("060" ,"ExampleActivity onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.v("060" ,"ExampleActivity onPause");
}
@Override
protected void onRestart() {
super.onRestart();
Log.v("060" ,"ExampleActivity onRestart");
}
@Override
protected void onStop() {
super.onStop();
Log.v("060" ,"ExampleActivity onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.v("060" ,"ExampleActivity onDestroy");
}
}
情况1:资源相关的系统配置发生改变导致Acitivity被杀死并重新创建。
Caution: 你的Activity会在每次旋转屏幕时被destroyed与recreated。当屏幕改变方向时,系统会Destory与Recreate前台的activity,因为屏幕配置被改变,你的Activity可能需要加载另一些替代的资源(例如layout).
情况2:系统内存不足导致低优先级的Activity被杀死
/**
* **********************************************************************
* 非典型情况下的生命周期
* **********************************************************************
* */
//保证一定在活动被回收之前调用,保存该活动的数据。
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String string = "activity 被系统回收了怎么办?";
outState.putString("Activity", string);
}
//恢复onSaveInstanceState保存的数据,官方建议采用该方案
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
String tempData = savedInstanceState.getString("Activity");
Toast.makeText(ExampleActivity.this,tempData,Toast.LENGTH_SHORT).show();
}
AndroidManifest.xml
第一个Activity中
//创建意图对象
Intent intent = new Intent(this,TwoActivity.class);
//设置传递键值对
intent.putExtra("data",str);
//激活意图
startActivity(intent);
第二个Activity中
// 获取意图对象
Intent intent = getIntent();
//获取传递的值
String str =intent.getStringExtra("data");
//设置值
tv.setText(str);
第一个Activity中
//创建意图对象
Intent intent = newIntent(MainActivity.this,TwoActivity.class);
//用数据捆传递数据
Bundle bundle = new Bundle();
bundle.putString("data", str);
//把数据捆设置改意图
intent.putExtra("bun", bundle);
//激活意图
startActivity(intent);
第二个Activity
//获取Bundle
Intent intent = getIntent();
Bundle bundle =intent.getBundleExtra("bun");
String str =bundle.getString("data");
tv.setText(str);
第一个Activity中
Intent intent = new Intent(MainActivity.this,TwoActivity.class);
//用一种特殊方式开启Activity
startActivityForResult(intent, 11);
//设置数据
protected void onActivityResult(intrequestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode, data);
String str =data.getStringExtra("data");
tvOne.setText(str);
}
第二个activity中
//设置返回的数据
Intent intent = new Intent();
intent.putExtra("data",edtOne.getText().toString().trim());
setResult(3, intent);
//关闭当前activity
finish();
第一个Activity中
SharedPreferences sp = this.getSharedPreferences("info",1);
//获取sp编辑器
Editor edit = sp.edit();
edit.putString("data", str);
edit.commit();
//创建意图对象
Intent intent = newIntent(MainActivity.this,TwoActivity.class);
//激活意图
startActivity(intent);
第二个Activity中
SharedPreferences sp =this.getSharedPreferences("info", 1);
//设置数据
tv.setText(sp.getString("data",""));
实际中,创建一个SharedPreferencesUtils类
publicclass SharedPreferencesUtils {
static SharedPreferencesUtils instance;
private SharedPreferences mSharedPreferences;
public SharedPreferencesUtils() {
mSharedPreferences =SmartApplication.getContext().getSharedPreferences(SpConstant.SP_NAME,Activity.MODE_PRIVATE);
}
// 单例模式
public static synchronized SharedPreferencesUtils getInstance() {
if (instance == null) {
instance = new SharedPreferencesUtils();
}
return instance;
}
public void putString(String key, String value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
public String getString(String key) {
return mSharedPreferences.getString(key, "");
}
public void putInt(String key, int value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putInt(key, value);
editor.commit();
}
public int getInt(String key) {
return mSharedPreferences.getInt(key, 0);
}
publicvoid putBoolean(String key, boolean value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putBoolean(key, value);
editor.commit();
}
public Boolean getBoolean(String key) {
return mSharedPreferences.getBoolean(key, false);
}
public Boolean getTuisong(String key)
{
return mSharedPreferences.getBoolean(key, true);
}
public void remove(String key) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.remove(key);
editor.commit();
}
public void putLong(String key, long value) {
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putLong(key, value);
editor.commit();
}
public int getLong(String key) {
return (int) mSharedPreferences.getLong(key, (long)0);
}
}
工具类
import java.io.Serializable;
class DataBean implements Serializable {
private String name;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
第一个Activity
//创建意图
Intent intent = new Intent(MainActivity.this,TwoActivity.class);
DataBean bean = new DataBean();
//通过set方法把数据保存到DataBean对象中
bean.setName("啦啦");
bean.setSex("男");
intent.putExtra("key", bean);
startActivity(intent);
第二个Activity
Intent intent = getIntent();
//反序列化数据对象
Serializable se =intent.getSerializableExtra("key");
if(se instanceof DataBean){
//获取到携带数据的DataBean对象db
DataBean db = (DataBean) se;
tv.setText(db.getName()+"==="+db.getSex());
}
第一个Activity
Intent intent = newIntent(MainActivity.this,TwoActivity.class);
TwoActivity.name="牛逼";
TwoActivity.str="你说";
startActivity(intent);
第二个Activity
//静态变量
protected static String name;
protected static String str;
tv.setText(str+name);
一般启动一个新的Activity都默认有切换的动画效果,比如界面从右至左的移动。退出一个Activity都默认有切换的动画效果,比如界面从左至右的移动。
启动的默认切换效果,与lauchmode有关系。
启动:
Intent intent = new Intent(ExampleActivity.this,Activity22.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
Bundle bundle = new Bundle();
bundle.putString("data", str);
intent.putExtra("bun", bundle);
startActivity(intent);
退出:
@Override
public void onBackPressed() {
super.onBackPressed();
overridePendingTransition(0,0);
}
或者
finish();
overridePendingTransition(0,0);
Android Activity切换动画常用实现方式
https://www.jianshu.com/p/6878d556c9cd