
Activity是與用戶交互的接口
Android系統(tǒng)是通過(guò)Activity棧的形式來(lái)管理Activity
下面我將會(huì)從以下幾個(gè)方面對(duì)Activity進(jìn)行總結(jié):
- Activity的四種展示形態(tài)
- Activity的啟動(dòng)模式
- Activity的生命周期
- Activity組件之間的通信
Activity四種形態(tài)
- Active(Activity處于棧頂)
- Paused (可見(jiàn)但不可交互,只是失去和用交互的能力)
- Stopped (不可見(jiàn),被另一個(gè)Activity完全覆蓋,在內(nèi)存足夠時(shí),數(shù)據(jù)、狀態(tài)、變量都被保存,內(nèi)存不足時(shí),數(shù)據(jù)、狀態(tài)、變量被系統(tǒng)回收掉)
- killed (系統(tǒng)回收掉)
Activity啟動(dòng)模式
Standard
系統(tǒng)默認(rèn)的啟動(dòng)模式,Activity可多次被實(shí)例化,一個(gè)任務(wù)棧中會(huì)有多個(gè)實(shí)例。
應(yīng)用場(chǎng)景:系統(tǒng)默認(rèn)-
SingleTop
SingleTop分兩種情況:一種情況是Activity位于棧頂,另一種是Activity不在棧頂時(shí),但存在于棧中。- 當(dāng)Activity在棧頂時(shí),啟用Activity,不會(huì)創(chuàng)建新的實(shí)例,并重用棧頂?shù)腁ctivity,通過(guò)onNewIntent()將Intent對(duì)象傳入這個(gè)實(shí)例中。
- 當(dāng)Activity不在棧頂時(shí),但存在于棧中,會(huì)啟用與standard相同的模式
應(yīng)用場(chǎng)景:IM對(duì)話框,新聞客戶端推送
-
SingleTask
首先會(huì)根據(jù)taskAffinity(任務(wù)相關(guān)性)去尋找當(dāng)前是否存在一個(gè)對(duì)應(yīng)名字的任務(wù)棧,如果不存在,則建一個(gè)新的task放于棧頂,如果存在,則得到該任務(wù)棧,查找該任務(wù)棧中是否存在該Activity實(shí)例,若存在,系統(tǒng)會(huì)銷毀在Activity上的所有的Activity,最終使Activity置于棧頂,再回調(diào)onNewIntent()函數(shù)應(yīng)用場(chǎng)景:應(yīng)用的主界面
-
SingleInstance
Activity會(huì)在一個(gè)獨(dú)立的任務(wù)中啟動(dòng),并且在這個(gè)棧中只有這一個(gè)實(shí)例,而被該實(shí)例啟動(dòng)的其他Activity會(huì)自動(dòng)運(yùn)行在另一個(gè)任務(wù)中,再次啟動(dòng)時(shí)該實(shí)例會(huì)重用已存在的任務(wù)和實(shí)例,在AndroidManifest文件中的lauchMode屬性中設(shè)置。特性:
- 以SingleInstance模式啟動(dòng)的Activity具有全局唯一性
- 以SingleInstance模式啟動(dòng)的Activity具有獨(dú)占性
應(yīng)用場(chǎng)景:呼叫來(lái)電
Activity生命周期
Activity正常情況下的周期調(diào)用
Activity的生命周期就是Activity從創(chuàng)建到銷毀的一個(gè)過(guò)程,仿佛我們?nèi)藦某錾剿劳鲆粯印?/p>
Activity生命周期的方法:
- onCreate();創(chuàng)建
- onStart();運(yùn)行
- onResume();獲取焦點(diǎn)
- onPause();失去焦點(diǎn)
- onStop();暫停
- onDestroy();銷毀
- onRestart();重運(yùn)行
單個(gè)Activity的多種變化形式:
- 從無(wú)到有創(chuàng)建一個(gè)Activity
- 當(dāng)前的Activity失去焦點(diǎn)
- 從當(dāng)前的Activity跳轉(zhuǎn)到另一個(gè)Activity
- 當(dāng)前Activity被置入后臺(tái)
從創(chuàng)建一個(gè)Activity到銷毀的生命周期:
- 一個(gè)Activity剛創(chuàng)建時(shí)候的生命周期:
onCreate() ——> onStart() ——> onResume()
- Activity從創(chuàng)建到銷毀的生命周期:
onCreate() ——> onStart() ——> onResume() ——>onPause() ——> onStop() ——> onDestroy()
- Activity從啟動(dòng)到失去焦點(diǎn)生命周期:
onCreate() ——> onStart() ——> onResume() ——> onPause()
- Activity從啟動(dòng)到失去焦點(diǎn),再到獲取焦點(diǎn)的生命周期:
onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onResume()
- Activity從啟動(dòng)到后臺(tái)的生命周期:
onCreate() ——> onStart() ——> onResume() ——> onPause() ——>onStop()
- Activity從啟動(dòng)到后臺(tái),再到前臺(tái)的生命周期:
onCreate() ——> onStart() ——> onResume() ——> onPause() ——> onStop() ——> onRestart() ——> onStart() ——>onResume()
onStart()、onStop() 、 onResume()、 onPause() 的區(qū)別:
onStart和onStop是從Activity是否可見(jiàn)這個(gè)角度來(lái)回調(diào)的,而onResume和onPause是從Activity是否位于前臺(tái)這個(gè)角度來(lái)回調(diào)的。
兩個(gè)Activity從創(chuàng)建到銷毀
有兩個(gè)Activity,分別為A和B,在A已經(jīng)創(chuàng)建的情況下,創(chuàng)建B頁(yè)面,這里可能會(huì)出現(xiàn)兩種情況:
- 頁(yè)面B完全遮擋住頁(yè)面A
- 頁(yè)面B沒(méi)有完全遮擋住頁(yè)面A
頁(yè)面B完全遮擋住頁(yè)面A
當(dāng)頁(yè)面B完全遮擋住頁(yè)面A時(shí)的生命周期:


頁(yè)面B沒(méi)有完全遮擋住頁(yè)面A
將B頁(yè)面設(shè)為透明的,在AndroidManifest.xml中設(shè)置
android:theme="@android:style/Theme.Translucent"
當(dāng)頁(yè)面B沒(méi)有完全遮擋住頁(yè)面A時(shí)的生命周期:


從這兩種情況可以看到,當(dāng)頁(yè)面A沒(méi)有被遮擋的時(shí)候,是不走onStop() 方法的,并且在開啟一個(gè)新的頁(yè)面B之前,頁(yè)面A會(huì)先執(zhí)行onPause() 方法。
Activity異常情況下的周期調(diào)用
異常情況下多了兩個(gè)方法:onSaveInstanceState(),onRestoreInstanceState(),這兩個(gè)方法是出現(xiàn)異常情況下系統(tǒng)自動(dòng)調(diào)用的,通常 onSaveInstanceState() 只適合用于保存一些臨時(shí)性的狀態(tài),而 onPause() 適合用于數(shù)據(jù)的持久化保存。當(dāng)Activity被重新創(chuàng)建后,系統(tǒng)會(huì)調(diào)用 onRestoreInstanceState() 方法,此方法會(huì)將Activity銷毀時(shí)通過(guò) onSaveInstanceState() 保存的bundle對(duì)象作為一個(gè)對(duì)象傳給 onRestoreInstanceState() 方法,同時(shí)也會(huì)傳遞給 onCreate() 方法。
onRestoreInstanceState() 方法與 onCreate() 方法都可以進(jìn)行數(shù)據(jù)恢復(fù),他兩區(qū)別在于:onRestoreInstanceState()傳入的參數(shù)一定不能為空,onCreate() 傳入的參數(shù)有可能為空,所以使用onRestoreInstanceState() 進(jìn)行數(shù)據(jù)恢復(fù)比較好。
onRestoreInstanceState() 方法在 onStart() 之后執(zhí)行,onSaveInstanceState() 方法在 onPause() 之后執(zhí)行。
下面看個(gè)橫豎屏切換的小例子觀察下onRestoreInstanceState()方法的調(diào)用
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: " + "調(diào)用onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
mTvShow.setText(savedInstanceState.getString(TURN));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: 調(diào)用onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_review);
ButterKnife.bind(this);
}
@Override
protected void onStart() {
Log.d(TAG, "onStart: 調(diào)用onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.d(TAG, "onResume: 調(diào)用onResume");
super.onResume();
}
@Override
protected void onRestart() {
Log.d(TAG, "onRestart: 調(diào)用onRestart");
super.onRestart();
}
@Override
protected void onPause() {
Log.d(TAG, "onPause: 調(diào)用onPause");
super.onPause();
}
@Override
protected void onStop() {
Log.d(TAG, "onStop: 調(diào)用onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy: 調(diào)用onDestroy");
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "onSaveInstanceState: 調(diào)用onSaveInstanceState");
super.onSaveInstanceState(outState);
outState.putString(TURN, mEtName.getText().toString());
}
@OnClick(R.id.bt_sure)
public void onViewClicked() {
mTvShow.setText(mEtName.getText().toString());
}
}
運(yùn)行后的效果:


最后防止重新創(chuàng)建activity:
可以在AndroidManifest.xml中指定configChange屬性來(lái)不讓系統(tǒng)重新創(chuàng)建
<activity
android:name=".activity.ReviewActivity"
android:configChanges="orientation|screenSize" />
/**
* @param newConfig :
* @return : void
* @date 創(chuàng)建時(shí)間: 2018/12/1
* @author lady_zhou
* @Description activity不被重建
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d(TAG, "onConfigurationChanged: 切屏防止activity調(diào)用onSaveInstanceState");
super.onConfigurationChanged(newConfig);
}


Activity與Fragment生命周期關(guān)系
從創(chuàng)建一個(gè)含有Fragment的Activity到 銷毀的生命周期:
Fragment生命周期的方法:
- onAttach();fragment已經(jīng)關(guān)聯(lián)到activity,只調(diào)用一次
- onCreate();系統(tǒng)創(chuàng)建fragment的時(shí)候回調(diào)他,只調(diào)用一次
- onCreateView();繪制layout
- onActivityCreated();當(dāng)Activity中的onCreate方法執(zhí)行完后調(diào)用。
- onStart();運(yùn)行
- onResume();獲取焦點(diǎn)
- onPause();失去焦點(diǎn)
- onStop();暫停
- onDestroyView();Fragment中的布局被移除時(shí)調(diào)用
- onDestroy();銷毀
- onDetach();Fragment和Activity解除關(guān)聯(lián)的時(shí)候調(diào)用
與Activity一樣Fragment也有的多種變化形式:
- 從無(wú)到有創(chuàng)建一個(gè)Fragment
- 當(dāng)前Activity被置入后臺(tái)
- 剛創(chuàng)建時(shí)候的生命周期:
Activity中onCreate()——>Activity中onStart()——>Fragment中onAttach()——>Fragment中onCreate()——>Fragment中onCreateView()——>Fragment中onActivityCreated()——>Fragment中onStart()——>Activity中onResume()——> Fragment中onResume()
- 從創(chuàng)建到銷毀的生命周期:
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()
- 從啟動(dòng)到后臺(tái)的生命周期:
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()
- 從啟動(dòng)到后臺(tái),再到前臺(tái)的生命周期:
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: 調(diào)用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: 調(diào)用onStart");
super.onStart();
}
@Override
protected void onResume() {
Log.d(TAG, "Activity: 調(diào)用onResume");
super.onResume();
}
@Override
protected void onRestart() {
Log.d(TAG, "Activity: 調(diào)用onRestart");
super.onRestart();
}
@Override
protected void onPause() {
Log.d(TAG, "Activity: 調(diào)用onPause");
super.onPause();
}
@Override
protected void onStop() {
Log.d(TAG, "Activity: 調(diào)用onStop");
super.onStop();
}
@Override
protected void onDestroy() {
Log.d(TAG, "Activity: 調(diào)用onDestroy");
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "Activity: 調(diào)用onSaveInstanceState");
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "Activity: " + "調(diào)用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: 調(diào)用onAttach");
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "Fragment: 調(diào)用onCreate");
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "Fragment: 調(diào)用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: 調(diào)用 onActivityCreated");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.d(TAG, "Fragment: 調(diào)用 onStart");
super.onStart();
}
@Override
public void onResume() {
Log.d(TAG, "Fragment: 調(diào)用 onResume");
super.onResume();
}
@Override
public void onPause() {
Log.d(TAG, "Fragment: 調(diào)用 onPause");
super.onPause();
}
@Override
public void onStop() {
Log.d(TAG, "Fragment: 調(diào)用 onStop");
super.onStop();
}
@Override
public void onDestroyView() {
Log.d(TAG, "Fragment: 調(diào)用 onDestroyView");
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onDestroy() {
Log.d(TAG, "Fragment: 調(diào)用 onDestroy");
super.onDestroy();
}
@Override
public void onDetach() {
Log.d(TAG, "Fragment: 調(diào)用 onDetach");
super.onDetach();
}
}

Activity組件之間的通信
我將Activity組件之間的通信分為以下三種:
1. Activity與Activity之間通信
2. Activity與Fragment之間通信
3. Activity與Service數(shù)據(jù)通信
Activity與Activity之間通信
Activity與Activity之間通信主要有以下幾種方式
1. Intent/Bundle
2. 類靜態(tài)變量
3. 全局變量
4. EventBus
這里主要是介紹第一種方式:Intent/Bundle
第一個(gè)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);
}
}
第二個(gè)Activity,顯示從第一個(gè)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("傳來(lái)的名字是:\t" + name);
mTvAge.setText("傳來(lái)的年齡是:\t" + age);
}
}

Activity與Fragment之間通信
其中Activity與Fragment之間通信又可以分為
- Activity傳遞數(shù)據(jù)給Fragment
- Fragment傳遞數(shù)據(jù)給Activity
Fragment 與 Activity 通信存在三種情形:
1. Activity 操作內(nèi)嵌的 Fragment,
2. Fragment 操作宿主 Activity,
3. Fragment 操作同屬 Activity中的其他 Fragment。
下面的demo主要是基于前兩種情形
Activity傳遞數(shù)據(jù)給Fragment的方法我總結(jié)為兩點(diǎn):
1. 使用Bundle
2. 直接在Activity中定義方法
我這里主要介紹使用Bundle方法
步驟在代碼里已經(jīng)注釋清楚了
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: 調(diào)用onCreateView");
View view = inflater.inflate(R.layout.activity_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
if(isAdded()) {//判斷Fragment已經(jīng)依附Activity
//收到Activity傳來(lái)的值第一步 獲取從Activity中傳過(guò)來(lái)的全部值
savedInstanceState = this.getArguments();
//收到Activity傳來(lái)的值第二步 獲取某一個(gè)值
if (savedInstanceState != null) {
String message = savedInstanceState.getString("message");
mTvText.setText("我是fragment\n Activity傳過(guò)來(lái)的值:" + message);
}
}
return view;
}
}
對(duì)應(yīng)的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: 調(diào)用onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_fragment);
ButterKnife.bind(this);
//第一步獲取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
//第二步獲取FragmentTransaction
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//第三步創(chuàng)建需要添加的Fragment
MyFragment mFragment = new MyFragment();
//第四步創(chuàng)建Bundle對(duì)象
Bundle bundle = new Bundle();
//第五步往bundle中添加數(shù)據(jù)
bundle.putString("message", "Activity往Fragment中傳值");
//第六步 將數(shù)據(jù)添加在fragment中
mFragment.setArguments(bundle);
//第七步 動(dòng)態(tài)添加fragment
fragmentTransaction.replace(R.id.fragment, mFragment);
fragmentTransaction.commit();
}
}
Fragment傳遞數(shù)據(jù)給Activity的方法也有很多:
1. Handler
2. 廣播
3. EventBus
4. 接口回調(diào)
5. Bundle和setArguments(bundle)
我這里主要介紹Fragment傳遞數(shù)據(jù)給Activity的方法中的接口回調(diào)
實(shí)現(xiàn)Fragment傳遞數(shù)據(jù)給Activity的接口回調(diào)主要分四步:
第一步: 定義回調(diào)接口
第二步: 定義接口屬性
第三步: 獲取相應(yīng)的Activity
第四步: 調(diào)用接口中的方法
下面是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: 調(diào)用onAttach");
super.onAttach(context);
if (context instanceof FragmentCallBack) {
mFragmentCallBack = (FragmentCallBack) context;//回傳Activity第三步 獲取相應(yīng)的Activity
} else {
throw new IllegalArgumentException("接口必須是FragmentCallBack");
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "Fragment: 調(diào)用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: 調(diào)用 onDestroyView");
super.onDestroyView();
unbinder.unbind();
}
/**
* @return : void
* @date 創(chuàng)建時(shí)間: 2019/1/16
* @author lady_zhou
* @Description 將傳遞進(jìn)來(lái)的Activity對(duì)象釋放掉
*/
@Override
public void onDetach() {
Log.d(TAG, "Fragment: 調(diào)用 onDetach");
super.onDetach();
mFragmentCallBack = null;
}
@OnClick(R.id.bt_button)
public void onViewClicked(View view) {
mFragmentCallBack.sendContent("從Fragment中回傳回來(lái)的值");//回傳Activity第四步 調(diào)用接口中的方法
}
}
/**
* @author lady_zhou
* @createTime: 2019/2/6
* @Description 回傳Activity第一步 定義回調(diào)接口
*/
public interface FragmentCallBack {
void sendContent(String info);
}
對(duì)應(yīng)的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: 調(diào)用onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_to_fragment);
ButterKnife.bind(this);
//獲取FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
//獲取FragmentTransaction
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//創(chuàng)建需要添加的Fragment
MyFragment mFragment = new MyFragment();
// 動(dòng)態(tài)添加fragment
fragmentTransaction.replace(R.id.fragment, mFragment);
fragmentTransaction.commit();
}
/**
* @param info : Activity返回的值
* @return : void
* @date 創(chuàng)建時(shí)間: 2019/2/6
* @author lady_zhou
* @Description 實(shí)現(xiàn)回調(diào)接口
*/
@Override
public void sendContent(String info) {
if (info != null) {
mTvBack.setText("這是Activity\n從Fragment返回的值是:" + info);
}
}

Activity與Service數(shù)據(jù)通信
Activity與Service數(shù)據(jù)通信主要有以下幾個(gè)方法:
1. 綁定服務(wù),利用ServiceConnection類(在Activity中實(shí)現(xiàn)這個(gè)類,同時(shí)實(shí)現(xiàn)onServiceConnected() 和onServiceDisconnected() 方法)
2. 簡(jiǎn)單通信,利用Intent進(jìn)行傳值
3. 定義一個(gè)回調(diào)接口來(lái)監(jiān)聽(tīng)服務(wù)中的進(jìn)程的變化使用handle切換到主線程
下面的下載小demo使用第一種和第三種方法,主要實(shí)現(xiàn)構(gòu)想是:
點(diǎn)擊下載后,進(jìn)度條顯示當(dāng)前下載的進(jìn)度(沒(méi)有使用網(wǎng)絡(luò),只是個(gè)小demo),代碼很簡(jiǎn)單應(yīng)該很容易看懂
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;
//綁定服務(wù)第一步: 先創(chuàng)建服務(wù)中的binder對(duì)象
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);//綁定服務(wù)
}
ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//綁定服務(wù)第二步: 獲取到DownLoadService返回的binder對(duì)象,并開啟服務(wù)
mDownLoadService = ((DownLoadService.MyBinder) service).startService();
//注冊(cè)回調(diào)接口來(lái)接收下載進(jìn)度的變化
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解綁服務(wù)");
}
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);
//切換到主線程顯示進(jìn)度
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();
}
}
下載服務(wù)實(shí)現(xiàn):
public class DownLoadService extends Service {
private final String TAG = getClass().getSimpleName();
//進(jìn)度條的最大值
public static final int MAX_PROGRESS = 100;
// 進(jìn)度條的進(jìn)度值
private int progress = 0;
private OnProgressListener onProgressListener;
private Thread mThread;
/**
* @param intent : 返回一個(gè)Binder對(duì)象
* @return : android.os.IBinder
* @date 創(chuàng)建時(shí)間: 2019/1/16
* @author lady_zhou
* @Description
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
startDownLoad();
return new MyBinder();
}
public class MyBinder extends Binder {
/**
* 獲取當(dāng)前Service的實(shí)例
*
* @return
*/
public DownLoadService startService() {
return DownLoadService.this;
}
}
/**
* @return : void
* @date 創(chuàng)建時(shí)間: 2019/1/16
* @author lady_zhou
* @Description 模擬下載任務(wù),每秒鐘更新一次
*/
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;
}
//進(jìn)度發(fā)生變化通知調(diào)用方
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 更新進(jìn)度的回調(diào)接口
*/
public interface OnProgressListener {
void onProgress(int progress);
}
/**
* @param onProgressListener :
* @return : void
* @date 創(chuàng)建時(shí)間: 2019/1/16
* @author lady_zhou
* @Description 注冊(cè)回調(diào)接口的方法,供外部調(diào)用
*/
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);
}
}
