赞
踩
Activity是与用户交互的接口
Android系统是通过Activity栈的形式来管理Activity
下面我将会从以下几个方面对Activity进行总结:
Standard
系统默认的启动模式,Activity可多次被实例化,一个任务栈中会有多个实例。
应用场景:系统默认
SingleTop
SingleTop分两种情况:一种情况是Activity位于栈顶,另一种是Activity不在栈顶时,但存在于栈中。
应用场景:IM对话框,新闻客户端推送
SingleTask
首先会根据taskAffinity(任务相关性)去寻找当前是否存在一个对应名字的任务栈,如果不存在,则建一个新的task放于栈顶,如果存在,则得到该任务栈,查找该任务栈中是否存在该Activity实例,若存在,系统会销毁在Activity上的所有的Activity,最终使Activity置于栈顶,再回调onNewIntent()函数
应用场景:应用的主界面
SingleInstance
Activity会在一个独立的任务中启动,并且在这个栈中只有这一个实例,而被该实例启动的其他Activity会自动运行在另一个任务中,再次启动时该实例会重用已存在的任务和实例,在AndroidManifest文件中的lauchMode属性中设置。
特性:
应用场景:呼叫来电
Activity的生命周期就是Activity从创建到销毁的一个过程,仿佛我们人从出生到死亡一样。
从创建一个Activity到销毁的生命周期:
onCreate() ——> onStart() ——> onResume()
onCreate() ——> onStart() ——> onResume() ——>onPause() ——> onStop() ——> onDestroy()
onCreate() ——> onStart() ——> onResume() ——> onPause()
onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onResume()
onCreate() ——> onStart() ——> onResume() ——> onPause() ——>onStop()
onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onStop() ——> onRestart() ——> onStart() ——>onResume()
有两个Activity,分别为A和B,在A已经创建的情况下,创建B页面,这里可能会出现两种情况:
当页面B完全遮挡住页面A时的生命周期:
将B页面设为透明的,在AndroidManifest.xml中设置
android:theme="@android:style/Theme.Translucent"
当页面B没有完全遮挡住页面A时的生命周期:
从这两种情况可以看到,当页面A没有被遮挡的时候,是不走onStop() 方法的,并且在开启一个新的页面B之前,页面A会先执行onPause() 方法。
异常情况下多了两个方法:onSaveInstanceState(),onRestoreInstanceState(),这两个方法是出现异常情况下系统自动调用的,通常 onSaveInstanceState() 只适合用于保存一些临时性的状态,而 onPause() 适合用于数据的持久化保存。当Activity被重新创建后,系统会调用 onRestoreInstanceState() 方法,此方法会将Activity销毁时通过 onSaveInstanceState() 保存的bundle对象作为一个对象传给 onRestoreInstanceState() 方法,同时也会传递给 onCreate() 方法。
onRestoreInstanceState() 方法与 onCreate() 方法都可以进行数据恢复,他两区别在于:onRestoreInstanceState()传入的参数一定不能为空,onCreate() 传入的参数有可能为空,所以使用onRestoreInstanceState() 进行数据恢复比较好。
onRestoreInstanceState() 方法在 onStart() 之后执行,onSaveInstanceState() 方法在 onPause() 之后执行。
下面看个横竖屏切换的小例子观察下onRestoreInstanceState()方法的调用
public class ReviewActivity extends AppCompatActivity { private final String TAG = ReviewActivity.class.getSimpleName(); private static final String TURN = "turn"; @BindView(R.id.et_name) EditText mEtName; @BindView(R.id.tv_show) TextView mTvShow; @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { Log.d(TAG, "onRestoreInstanceState: " + "调用onRestoreInstanceState"); super.onRestoreInstanceState(savedInstanceState); mTvShow.setText(savedInstanceState.getString(TURN)); } @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate: 调用onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_review); ButterKnife.bind(this); } @Override protected void onStart() { Log.d(TAG, "onStart: 调用onStart"); super.onStart(); } @Override protected void onResume() { Log.d(TAG, "onResume: 调用onResume"); super.onResume(); } @Override protected void onRestart() { Log.d(TAG, "onRestart: 调用onRestart"); super.onRestart(); } @Override protected void onPause() { Log.d(TAG, "onPause: 调用onPause"); super.onPause(); } @Override protected void onStop() { Log.d(TAG, "onStop: 调用onStop"); super.onStop(); } @Override protected void onDestroy() { Log.d(TAG, "onDestroy: 调用onDestroy"); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { Log.d(TAG, "onSaveInstanceState: 调用onSaveInstanceState"); super.onSaveInstanceState(outState); outState.putString(TURN, mEtName.getText().toString()); } @OnClick(R.id.bt_sure) public void onViewClicked() { mTvShow.setText(mEtName.getText().toString()); } }
运行后的效果:
最后防止重新创建activity:
可以在AndroidManifest.xml中指定configChange属性来不让系统重新创建
<activity
android:name=".activity.ReviewActivity"
android:configChanges="orientation|screenSize" />
/**
* @param newConfig :
* @return : void
* @date 创建时间: 2018/12/1
* @author lady_zhou
* @Description activity不被重建
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d(TAG, "onConfigurationChanged: 切屏防止activity调用onSaveInstanceState");
super.onConfigurationChanged(newConfig);
}
从创建一个含有Fragment的Activity到 销毁的生命周期:
Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()
Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onStop()——>Fragment中onStop()——>Activity中onDestroy()——>Fragment中onDestroyView()——>Fragment中onDestroy()——>Fragment中onDetach()
Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onSaveInstanceState()——>Activity中onStop()——>Fragment中onStop()
Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()——>Activity中onPause()——>Fragment中onPause()——>Activity中onSaveInstanceState()——>Activity中onStop()——>Fragment中onStop()——>Activity中onRestart()——>Activity中onStart()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()
public class ActivityToFragmentActivity extends AppCompatActivity implements MyFragment.FragmentCallBack { private static final String TAG = "Fragment"; @BindView(R.id.tv_back) TextView mTvBack; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "Activity: 调用onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_to_fragment); ButterKnife.bind(this); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); MyFragment mFragment = new MyFragment(); fragmentTransaction.replace(R.id.fragment, mFragment); fragmentTransaction.commit(); } @Override protected void onStart() { Log.d(TAG, "Activity: 调用onStart"); super.onStart(); } @Override protected void onResume() { Log.d(TAG, "Activity: 调用onResume"); super.onResume(); } @Override protected void onRestart() { Log.d(TAG, "Activity: 调用onRestart"); super.onRestart(); } @Override protected void onPause() { Log.d(TAG, "Activity: 调用onPause"); super.onPause(); } @Override protected void onStop() { Log.d(TAG, "Activity: 调用onStop"); super.onStop(); } @Override protected void onDestroy() { Log.d(TAG, "Activity: 调用onDestroy"); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { Log.d(TAG, "Activity: 调用onSaveInstanceState"); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { Log.d(TAG, "Activity: " + "调用onRestoreInstanceState"); super.onRestoreInstanceState(savedInstanceState); } }
Fragment
public class MyFragment extends Fragment { private static final String TAG = "Fragment"; @BindView(R.id.tv_text) TextView mTvText; Unbinder unbinder; @Override public void onAttach(Context context) { Log.d(TAG, "Fragment: 调用onAttach"); super.onAttach(context); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { Log.d(TAG, "Fragment: 调用onCreate"); super.onCreate(savedInstanceState); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d(TAG, "Fragment: 调用onCreateView"); View view = inflater.inflate(R.layout.activity_fragment, container, false); unbinder = ButterKnife.bind(this, view); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { Log.d(TAG, "Fragment: 调用 onActivityCreated"); super.onActivityCreated(savedInstanceState); } @Override public void onStart() { Log.d(TAG, "Fragment: 调用 onStart"); super.onStart(); } @Override public void onResume() { Log.d(TAG, "Fragment: 调用 onResume"); super.onResume(); } @Override public void onPause() { Log.d(TAG, "Fragment: 调用 onPause"); super.onPause(); } @Override public void onStop() { Log.d(TAG, "Fragment: 调用 onStop"); super.onStop(); } @Override public void onDestroyView() { Log.d(TAG, "Fragment: 调用 onDestroyView"); super.onDestroyView(); unbinder.unbind(); } @Override public void onDestroy() { Log.d(TAG, "Fragment: 调用 onDestroy"); super.onDestroy(); } @Override public void onDetach() { Log.d(TAG, "Fragment: 调用 onDetach"); super.onDetach(); } }
我将Activity组件之间的通信分为以下三种:
1. Activity与Activity之间通信
2. Activity与Fragment之间通信
3. Activity与Service数据通信
Activity与Activity之间通信主要有以下几种方式
1. Intent/Bundle
2. 类静态变量
3. 全局变量
4. EventBus
这里主要是介绍第一种方式:Intent/Bundle
第一个Activity
public class OneActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_one); ButterKnife.bind(this); } @OnClick(R.id.bt_to_activity) public void onViewClicked() { Bundle bundle = new Bundle(); bundle.putInt("age", 19); bundle.putString("name", "雷东宝"); Intent intent = new Intent(OneActivity.this, SecondActivity.class); intent.putExtras(bundle); startActivity(intent); } }
第二个Activity,显示从第一个Activity中传入的名字和年龄
public class SecondActivity extends AppCompatActivity { @BindView(R.id.tv_name) TextView mTvName; @BindView(R.id.tv_age) TextView mTvAge; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); ButterKnife.bind(this); //用getIntent()方法获取intent Intent intent = getIntent(); String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age", 0); mTvName.setText("传来的名字是:\t" + name); mTvAge.setText("传来的年龄是:\t" + age); } }
其中Activity与Fragment之间通信又可以分为
Fragment 与 Activity 通信存在三种情形:
1. Activity 操作内嵌的 Fragment,
2. Fragment 操作宿主 Activity,
3. Fragment 操作同属 Activity中的其他 Fragment。
下面的demo主要是基于前两种情形
Activity传递数据给Fragment的方法我总结为两点:
1. 使用Bundle
2. 直接在Activity中定义方法
我这里主要介绍使用Bundle方法
步骤在代码里已经注释清楚了
Fragment
public class MyFragment extends Fragment { private static final String TAG = "Fragment"; @BindView(R.id.tv_text) TextView mTvText; Unbinder unbinder; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d(TAG, "Fragment: 调用onCreateView"); View view = inflater.inflate(R.layout.activity_fragment, container, false); unbinder = ButterKnife.bind(this, view); if(isAdded()) {//判断Fragment已经依附Activity //收到Activity传来的值第一步 获取从Activity中传过来的全部值 savedInstanceState = this.getArguments(); //收到Activity传来的值第二步 获取某一个值 if (savedInstanceState != null) { String message = savedInstanceState.getString("message"); mTvText.setText("我是fragment\n Activity传过来的值:" + message); } } return view; } }
对应的Activity
public class ActivityToFragmentActivity extends AppCompatActivity { private static final String TAG = "Fragment"; @BindView(R.id.tv_back) TextView mTvBack; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "Activity: 调用onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_to_fragment); ButterKnife.bind(this); //第一步获取FragmentManager FragmentManager fragmentManager = getSupportFragmentManager(); //第二步获取FragmentTransaction FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); //第三步创建需要添加的Fragment MyFragment mFragment = new MyFragment(); //第四步创建Bundle对象 Bundle bundle = new Bundle(); //第五步往bundle中添加数据 bundle.putString("message", "Activity往Fragment中传值"); //第六步 将数据添加在fragment中 mFragment.setArguments(bundle); //第七步 动态添加fragment fragmentTransaction.replace(R.id.fragment, mFragment); fragmentTransaction.commit(); } }
Fragment传递数据给Activity的方法也有很多:
1. Handler
2. 广播
3. EventBus
4. 接口回调
5. Bundle和setArguments(bundle)
我这里主要介绍Fragment传递数据给Activity的方法中的接口回调
实现Fragment传递数据给Activity的接口回调主要分四步:
第一步: 定义回调接口
第二步: 定义接口属性
第三步: 获取相应的Activity
第四步: 调用接口中的方法
下面是Fragment中的代码:
public class MyFragment extends Fragment { private static final String TAG = "Fragment"; @BindView(R.id.tv_text) TextView mTvText; Unbinder unbinder; //回传Activity第二步 定义属性 private FragmentCallBack mFragmentCallBack; @Override public void onAttach(Context context) { Log.d(TAG, "Fragment: 调用onAttach"); super.onAttach(context); if (context instanceof FragmentCallBack) { mFragmentCallBack = (FragmentCallBack) context;//回传Activity第三步 获取相应的Activity } else { throw new IllegalArgumentException("接口必须是FragmentCallBack"); } } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d(TAG, "Fragment: 调用onCreateView"); View view = inflater.inflate(R.layout.activity_fragment, container, false); unbinder = ButterKnife.bind(this, view); return view; } @Override public void onDestroyView() { Log.d(TAG, "Fragment: 调用 onDestroyView"); super.onDestroyView(); unbinder.unbind(); } /** * @return : void * @date 创建时间: 2019/1/16 * @author lady_zhou * @Description 将传递进来的Activity对象释放掉 */ @Override public void onDetach() { Log.d(TAG, "Fragment: 调用 onDetach"); super.onDetach(); mFragmentCallBack = null; } @OnClick(R.id.bt_button) public void onViewClicked(View view) { mFragmentCallBack.sendContent("从Fragment中回传回来的值");//回传Activity第四步 调用接口中的方法 } } /** * @author lady_zhou * @createTime: 2019/2/6 * @Description 回传Activity第一步 定义回调接口 */ public interface FragmentCallBack { void sendContent(String info); }
对应的Activity的代码:
public class ActivityToFragmentActivity extends AppCompatActivity implements MyFragment.FragmentCallBack { private static final String TAG = "Fragment"; @BindView(R.id.tv_back) TextView mTvBack; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "Activity: 调用onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_to_fragment); ButterKnife.bind(this); //获取FragmentManager FragmentManager fragmentManager = getSupportFragmentManager(); //获取FragmentTransaction FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); //创建需要添加的Fragment MyFragment mFragment = new MyFragment(); // 动态添加fragment fragmentTransaction.replace(R.id.fragment, mFragment); fragmentTransaction.commit(); } /** * @param info : Activity返回的值 * @return : void * @date 创建时间: 2019/2/6 * @author lady_zhou * @Description 实现回调接口 */ @Override public void sendContent(String info) { if (info != null) { mTvBack.setText("这是Activity\n从Fragment返回的值是:" + info); } }
Activity与Service数据通信主要有以下几个方法:
1. 绑定服务,利用ServiceConnection类(在Activity中实现这个类,同时实现onServiceConnected() 和onServiceDisconnected() 方法)
2. 简单通信,利用Intent进行传值
3. 定义一个回调接口来监听服务中的进程的变化使用handle切换到主线程
下面的下载小demo使用第一种和第三种方法,主要实现构想是:
点击下载后,进度条显示当前下载的进度(没有使用网络,只是个小demo),代码很简单应该很容易看懂
Activity中的代码
public class ActivityToServiceActivity extends AppCompatActivity { private final String TAG = getClass().getSimpleName(); private static final String KEY = "data"; @BindView(R.id.bt_download) Button mBtDownload; @BindView(R.id.progressbar) ProgressBar mProgressbar; @BindView(R.id.tv_text) TextView mTvText; //绑定服务第一步: 先创建服务中的binder对象 private DownLoadService mDownLoadService = null; private Intent mIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_to_service); ButterKnife.bind(this); mIntent = new Intent(ActivityToServiceActivity.this, DownLoadService.class); } @OnClick(R.id.bt_download) public void onViewClicked() { bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);//绑定服务 } ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //绑定服务第二步: 获取到DownLoadService返回的binder对象,并开启服务 mDownLoadService = ((DownLoadService.MyBinder) service).startService(); //注册回调接口来接收下载进度的变化 mDownLoadService.setOnProgressListener(new DownLoadService.OnProgressListener() { @Override public void onProgress(int progress) { mProgressbar.setProgress(progress); //使用Handle Message message = new Message(); Bundle bundle = new Bundle(); bundle.putInt(KEY, progress); message.setData(bundle); mHandler.sendMessage(message); if (progress == 100) { unbindService(mServiceConnection); mDownLoadService = null; Log.d(TAG, "方法:onProgress: \t\t解绑服务"); } Log.d(TAG, "方法:onProgress: \t\t" + progress); } }); } @Override public void onServiceDisconnected(ComponentName name) { } }; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //切换到主线程显示进度 mTvText.setText(msg.getData().getInt(KEY,0)+"%"); if(msg.getData().getInt(KEY,0)==100){ Toast.makeText(ActivityToServiceActivity.this, "下载完成", Toast.LENGTH_SHORT).show(); } } }; @Override protected void onDestroy() { if (mDownLoadService != null) { unbindService(mServiceConnection); } super.onDestroy(); } }
下载服务实现:
public class DownLoadService extends Service { private final String TAG = getClass().getSimpleName(); //进度条的最大值 public static final int MAX_PROGRESS = 100; // 进度条的进度值 private int progress = 0; private OnProgressListener onProgressListener; private Thread mThread; /** * @param intent : 返回一个Binder对象 * @return : android.os.IBinder * @date 创建时间: 2019/1/16 * @author lady_zhou * @Description */ @Nullable @Override public IBinder onBind(Intent intent) { startDownLoad(); return new MyBinder(); } public class MyBinder extends Binder { /** * 获取当前Service的实例 * * @return */ public DownLoadService startService() { return DownLoadService.this; } } /** * @return : void * @date 创建时间: 2019/1/16 * @author lady_zhou * @Description 模拟下载任务,每秒钟更新一次 */ public void startDownLoad() { mThread = new Thread(new Runnable() { @Override public void run() { while (progress < MAX_PROGRESS) { progress += 10; //中断线程 if (Thread.currentThread().isInterrupted()) { Log.d(TAG, "方法:run: \t\t中断线程"); break; } //进度发生变化通知调用方 if (onProgressListener != null) { onProgressListener.onProgress(progress); } try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } Log.d(TAG, "方法:run: 线程\t\t" + progress); } } }); mThread.start(); } /** * @author lady_zhou * @createTime: 2019/1/16 * @Description 更新进度的回调接口 */ public interface OnProgressListener { void onProgress(int progress); } /** * @param onProgressListener : * @return : void * @date 创建时间: 2019/1/16 * @author lady_zhou * @Description 注册回调接口的方法,供外部调用 */ public void setOnProgressListener(OnProgressListener onProgressListener) { this.onProgressListener = onProgressListener; } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "方法:onUnbind: \t\t解绑了"); mThread.interrupt();//中断线程 return super.onUnbind(intent); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。