天天看點

學習android開發文檔筆記心得之 ActivitiesTasks and Back Stack

Activities

   多activity的合作

當activity A啟動activity B時,兩個activity生命周期如下:

  1. Activity A的 onPause()方法,如果活動背景不可見的話,onStop()方法同樣運作,否則不運作。
  2. Activity B的 onCreate() ,onStart() 和onResume() 方法依次運作。(Activity B現在獲得使用者焦點。)

以上預設的生命周期回調方法順序使你能夠對一個activity啟動另一個activity時的轉換資訊進行管理。 例如,如果第一個activity停止時你須寫入資料庫以便後續的activity可以讀取資料,那麼你應該在 onPause() 方法而不是 onStop() 方法裡寫入資料庫。防止資料還未準備完畢時activity B就已經啟動。

Fragments

Fragment表現Activity中使用者界面的一個行為或者是一部分。你可以在一個單獨的activity上把多個fragment組合成為一個多區域的UI,并且可以在多個activity中再使用。你可以認為fragment是activity的一個子產品零件,它有自己的生命周期,接收它自己的輸入事件,并且可以在activity運作時添加或者删除。

fragment的生命周期與和他綁定的activity息息相關。且和activity一樣,可以通過onSaveInstanceState()方法儲存狀态。

建立fragment需要繼承fragment父類或者fragment父類的子類

學習android開發文檔筆記心得之 ActivitiesTasks and Back Stack

onCreate()

同activity一樣,可以在此方法中初始化一些需要的資料和控件等等。

onCreateView()

在第一次為fragment繪制使用者界面時系統會調用此方法。為fragment繪制使用者界面,這個函數必須要傳回所繪出的fragment的根View。如果fragment沒有使用者界面可以傳回空。

onPause()

當使用者離開fragment,第一個調用的方法,并不意味着此fragment一定會被銷毀,但是很有可能使用者不會再進入此界面,是以同activity一樣,需要在此生命周期裡做資料持久化操作。(同多activity的合作一樣)

處理Fragment事務

         在activity中使用fragment特點:可以任意添加、删除、替換、執行、響應使用者互動。使用例如add()、remove()、replace()等方法設定相關事務,然後通過commit()方法送出給activity。送出給activity之後并不意味着立即執行,而是 進行預約等待,知道主線程準備完畢才可運作。(調用executePendingTransations()方法可立即執行,但是一般不推薦)。

         假設使用者離開activity時,剛好commit()了一個fragment的事務,此時會抛出異常(爹都跑了兒子還玩個P),此時如果activity被恢複,那麼commit之後的狀态将丢失。如果存在這種情況,使用commitAllowingStateLoss(),提前告訴你兒子,你可能會走,在原地等我。          

與Activity互動

當建立了一個fragment執行個體之後,此fragment就會與對應的activity進行綁定,确認父子關系,fragment可以通過getactivity()方法擷取與之綁定的activity,進而可以通過唯一的id擷取activity中的view。反之activity也能通過getFragmentManager().findFragmentById擷取fragment。

建立activity事件回調函數

假設點選fragment中某一按鈕需要在activity中顯示對應的資訊,需要在此fragment中定義一個回調的接口,然後在宿主activity中實作此接口,當調用fragment中的onclick方法時,調用此接口的方法,就可以将資訊傳遞給自己。(實戰中大多通過activity傳遞給另外一個fragment)。

public class Fragment extends android.app.Fragment {
    EditText editText;
    Button button;
    onCallback oncallback;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment,null);
        editText = (EditText)view.findViewById(R.id.edit_query);
        button = view.findViewById(R.id.button3);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getText(oncallback);
            }
        });
        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            oncallback = (onCallback) activity;
        }catch (Exception o){
            
        }

    }

    public void getText(onCallback oncallback){
        String text = editText.getText().toString();
        if (text == null){
            text = "null";
        }
        oncallback.doThings(text);
    }

    public interface onCallback{
        public void doThings(String text);
    }
}      
public class MainActivity extends Activity implements View.OnClickListener {

    private TextView textView = null;
    FragmentManager fragmentManager;
    FragmentTransaction fragmentTransaction;
    Fragment fragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.text);
        fragmentManager = getFragmentManager();
        fragmentTransaction = fragmentManager.beginTransaction();
        fragment =new Fragment();
        fragment.oncallback = new Fragment.onCallback() {
            @Override
            public void doThings(String text) {
               textView.setText(text);
            }
        };
        fragmentTransaction.add(R.id.fragment,fragment);
        fragmentTransaction.commit();

    }
}      

添加items到Action Bar

     需要在fragment的oncreate()方法中調用setHasOptionsMenu(Boolean)方法将此屬性設定為true,否則後面将不會回調onCreateOptionsMenu()方法,也就不會調用onOptionsItemSelected()方法。

Tasks and Back Stack

     一個程式含有很多個activity,每個activity設計時都應該以執行某一個使用者發起的action為核心目标(例如app的main activity就是執行了

"android.intent.action.MAIN"

這一個action),且能夠啟動其他activity(startactivity等方法)。或者定義一個特定的攜帶action的intent來啟動在Androidmanifest中定義了此action的activity。很多時候可能有很多個activity都帶有同一個action參數,此時,系統會讓使用者選擇一個來打開。

通過action打開的activity即使和打開它的activity不屬于同一個應用,也将存在同一個task中。預設将壓入同一個棧中(按照啟動順序後進先出。)也可以在啟動的時候設定flag來選擇如何啟動activity。

可以使用的 <activity> 屬性主要有:

  • taskAffinity
  • launchMode 
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

可用的 intent 标志主要有:

  • FLAG_ACTIVITY_NEW_TASK 如果activity不存在,在一個新的棧中啟動,否則就将那個task調入前台顯示
  • FLAG_ACTIVITY_CLEAR_TOP 清除啟動的activity之上所有activity,并重新啟動activity
  • FLAG_ACTIVITY_SINGLE_TOP 如果啟動的activity不在棧頂,則在新的棧中啟動

使用 manifest 檔案

launchMode 屬性指明了 activity 啟動 task 的方式。 launchMode 屬性可設為四種啟動模式:

"standard" (預設模式)
預設值。系統在啟動 activity 的 task 中建立一個新的 activity 執行個體,并把 intent 傳送路徑指向它。該 activity 可以被執行個體化多次,各個執行個體可以屬于不同的 task,一個 task 中也可以存在多個執行個體。
"singleTop"
如果 activity 已經存在一個執行個體并位于目前 task 的棧頂,則系統會調用已有執行個體的 onNewIntent()方法把 intent 傳遞給已有執行個體,而不是建立一個新的 activity 執行個體。activity 可以被執行個體化多次,各個執行個體可以屬于不同的 task,一個 task 中可以存在多個執行個體(但僅當 back stack 頂的 activity 執行個體不是該 activity 的)。
"singleTask"
如果此activity已經存在,則調用該activity否則新起一個task來啟動此activity。 此 activity 同一時刻隻能存在一個執行個體。
"singleInstance"
除了系統不會把其它 activity 放入目前執行個體所在的 task 之外,其它均與 "singleTask"相同。activity 總是它所在 task 的唯一成員;它所啟動的任何 activity 都會放入其它 task 中。

繼續閱讀