Android:Activity和Fragment

Activity

一,Activity生命週期

onCreate()

創建Activity時被回調。

該方法做一些初始化動作,比如創建views,設置數據到list等等。

這個方法提供了一個Bundle類型的變量,該變量中有這個activity以前存儲過的狀態信息。

若在onCreate方法中加入finish()方法,onCreate下一個運行onDestory方法。

此時Activity還在後臺,不可見

onStart()

啓動Activity時被調用。

當activity在前臺顯示時,會運行onResume。

當activity還沒在前臺顯示就被隱藏(停止狀態)了會運行onStop(),比如在onStart方法中用了finish()方法的話,onStart()之後就會直接運行onStop→onDestory。

此時Activity已經可見了,但是還沒出現在前臺,我們還看不到,無法與Activity交互。

onResume()

恢復Activity時被回調,並且爲了用戶操作此時該activity位於activity棧的頂部。經過某些操作後該方法執行完後執行的是onPause()。

Activity在這個階段已經出現在前臺並且可見了。這個階段可以打開獨佔設備。

onPause()

暫停Activity時被回調。

當Activity要跳到另一個Activity或應用正常退出時都會執行這個方法。此時Activity在前臺並可見,我們可以進行一些輕量級的存儲數據和去初始化的工作,不能太耗時,因爲在跳轉Activity時只有當一個Activity執行完了onPause方法後另一個Activity纔會啓動,而且android中指定如果onPause在500ms即0.5秒內沒有執行完畢的話就會強制關閉Activity。從生命週期圖中發現可以在這快速重啓,但這種情況其實很罕見,比如用戶切到下一個Activity的途中按back鍵快速得切回來。

onStop()

停止Activity時被回調。

一個新的activity被執行,一個存在的activity被切換到最前端,這個activity要被銷燬。都會觸發onStop()方法。

如果用戶召回這個activity,那麼會調用onRestart方法。

如果用戶銷燬這個activity,那麼會調用onDestory方法。

此時Activity已經不可見了,但是Activity對象還在內存中,沒有被銷燬。這個階段的主要工作也是做一些資源的回收工作,用戶退出程序,建議在onStop方法中保存數據。

onDestory()

銷燬Activity時被回調。

activity調用了finish()方法來結束這個activity或者因爲系統爲了節省空間而臨時銷燬這個activity,這兩個情況可以通過isFinishing()方法判斷。

這個階段Activity被銷燬,不可見,我們可以將還沒釋放的資源釋放,以及進行一些回收工作。

onRestart()

重啓Activity時被調用。該方法優先於再次運動的onStart,運行完onRestart之後運行onStart。

在該方法中加入finish()語句,則還會繼續運行onStart及後面狀態方法直到onDestroy運行完成。

Activity在這時可見,當用戶按Home鍵切換到桌面後又切回來或者從後一個Activity切回前一個Activity就會觸發這個方法。這裏一般不做什麼操作。

 二,生命週期之間的區別

onCreate和onStart

(1)可見與不可見的區別。前者不可見,後者可見。
(2)執行次數的區別。onCreate方法只在Activity創建時執行一次,而onStart方法在Activity的切換以及按Home鍵返回桌面再切迴應用的過程中被多次調用。因此Bundle數據的恢復在onStart中進行比onCreate中執行更合適。
(3)onCreate能做的事onStart其實都能做,但是onstart能做的事onCreate卻未必適合做。如前文所說的,setContentView和資源初始化在兩者都能做,然而想動畫的初始化在onStart中做比較好。

onStart和onResume

(1)是否在前臺。onStart方法中Activity可見但不在前臺,不可交互,而在onResume中在前臺。
(2)職責不同,onStart方法中主要還是進行初始化工作,而onResume方法,根據官方的建議,可以做開啓動畫和獨佔設備的操作。

onPause和onStop

(1)是否可見。onPause時Activity可見,onStop時Activity不可見,但Activity對象還在內存中。
(2)在系統內存不足的時候可能不會執行onStop方法,因此程序狀態的保存、獨佔設備和動畫的關閉、以及一些數據的保存最好在onPause中進行,但要注意不能太耗時。

onStop和onDestroy

onStop階段Activity還沒有被銷燬,對象還在內存中,此時可以通過切換Activity再次回到該Activity,而onDestroy階段Acivity被銷燬。

 三,Activity配置

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
</application>

四,啓動Activity

直接啓動

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
StartActivity(intent);

Intent intent = new Intent();
ComponentName component = new ComponentName( MainActivity.this,SecondActivity.class);
intent.setComponent(component);
startActivity(intent);

匿名啓動

<activity android:name=".SecondActivity">
	<intent-filter>
		<action android:name="test"/>
		<category android:name="android.intent.category.DEFAULT"/>
	</intent-filter>
</activity>
Intent intent = new Intent();
intent.setAction("test");
startActivity(intent);

五,Activity之間的數據交換

putExtra

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("name","db");//以鍵值對的方式傳遞
StartActivity(intent);
在SecondActivity的代碼中獲取數據
Intent intent = getIntent();
if(intent!=null)
{
	String name = intent.getStringExtra("name");
}

putString

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name","db");
intent.putExtras(bundle);
StartActivity(intent);
//在SecondActivity的代碼中獲取數據和方法一相同

putSerializable

public class User implements Serializable{
	private String name;
	private int age;
	public User(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
}
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
User user = new User("db",20);
Bundle bundle = new Bundle();
bundle.putSerializable("User",user);
intent.putExtras(bundle);
StartActivity(intent);
在SecondActivity的代碼中獲取數據
Intent intent = getIntent();
if(intent!=null)
{
	User user = (User)intent.getSerializableExtra("User");
}

Fragement

參考:https://www.jianshu.com/p/9f538c3a1918

Fragment是可以讓你的app縱享絲滑的設計,如果你的app想在現在基礎上性能大幅度提高,並且佔用內存降低,同樣的界面Activity佔用內存比Fragment要多,響應速度Fragment比Activty在中低端手機上快了很多,甚至能達到好幾倍!如果你的app當前或以後有移植平板等平臺時,可以讓你節省大量時間和精力。

一,Fragement的優點

  • Fragment可以使你能夠將activity分離成多個可重用的組件,每個都有它自己的生命週期和UI。
  • Fragment可以輕鬆得創建動態靈活的UI設計,可以適應於不同的屏幕尺寸。從手機到平板電腦。
  • Fragment是一個獨立的模塊,緊緊地與activity綁定在一起。可以運行中動態地移除、加入、交換等。
  • Fragment提供一個新的方式讓你在不同的安卓設備上統一你的UI。
  • Fragment 解決Activity間的切換不流暢,輕量切換。
  • Fragment 替代TabActivity做導航,性能更好。
  • Fragment 在4.2.版本中新增嵌套fragmeng使用方法,能夠生成更好的界面效果。
  • Fragment做局部內容更新更方便,原來爲了到達這一點要把多個佈局放到一個activity裏面,現在可以用多Fragment來代替,只有在需要的時候才加載Fragment,提高性能

二,Fragement的生命週期

onAttach() 當Fragment被添加到Activity時被調用,該方法只會被調用一次。需要注意的是,初始化fragment參數可以從getArguments()獲得,但是,當Fragment附加到Activity之後,就無法再調用setArguments()。
onCreate(Bundle) 創建Fragment時被回調。該方法只會被調用一次。此時的Activity還沒有創建完成,因爲我們的Fragment也是Activity創建的一部分。所以如果你想在這裏使用Activity中的一些資源,將會獲取不到。
onCreateView() 每次創建、繪製Fragment的View組件都會調用。
onActivityCreated() 當Fragment所在的Activity被啓動完成後調用。所以到這裏的時候,Activity已經創建完成!在這個函數中才可以使用Activity的所有資源。如果把下面的代碼放在這裏,獲取到的btn_Try的值將不會再是空的!
onStart() 當Fragment即將可見時調用。在生命週期中也可以看到Fragment的OnStart()過程與Activity的OnStart()過程是綁定的。
onResume() 當Fragment即將獲得焦點時調用。從生命週期對比中,可以看到,Fragment的OnResume與Activity的OnResume是相互綁定的,意義是一樣的。它依賴於包含它的activity的Activity.onResume。當OnResume()結束後,就可以正式與用戶交互了。
onPause() 由活動狀態變成暫停狀態時調用,與Activity的OnPause()意義一樣。
onStop() 不可見時調用,進入停止狀態。這個回調與Activity的OnStop()相綁定,意義一樣。已停止的Fragment可以直接返回到OnStart()回調,然後調用OnResume()。
onDestroyView() 銷燬View組件時調用,在onStop()之後,onDestroy()之前調用。
onDestroy() Fragment對象銷燬時調用。需要注意的是,它即使經過了onDestroy()階段,但仍然能從Activity中找到,因爲它還沒有Detach。
onDetach() Fragment與Activity分離時調用。調用它以後,Fragment就不再與Activity相綁定,它也不再擁有視圖層次結構,它的所有資源都將被釋放。

三,創建Fragment

一,定義兩個Fragement的佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 1"
        android:textColor="#000000"
        android:textSize="25sp" />

</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0090FF" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is fragment 1"
        android:textColor="#000000"
        android:textSize="25sp" />

</LinearLayout>

二,自定義Fragment類

需要繼承Fragment或者他的子類,重寫onCreateView()方法 在該方法中調用:inflater.inflate()方法,加載Fragment的佈局文件,接着返回加載的view對象,我們分別創建兩個fragment的佈局。

import androidx.fragment.app.Fragment;

public class Fragement1 extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragement1, container,false);
        return view;
    }
}
==================================
public class Fragement2 extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragement1, container,false);
        return view;
    }
}

三,在Activity對應的佈局文件中添加fragment的標籤

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false" >

    <fragment
        android:id="@+id/fragment1"
        android:name="com.zzu.sunshaoqi.myapplication.Fragement1"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/fragment2"
        android:name="com.zzu.sunshaoqi.myapplication.Fragement2"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

四,調用setContentView()

import androidx.fragment.app.FragmentActivity;

public class MainActivity extends FragmentActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:baselineAligned="false" >

    <Button
        android:id="@+id/btn_show_fragment1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="顯示Fragment1"/>

    <Button
        android:id="@+id/btn_show_fragment2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="顯示Fragment2"/>

    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

 

public class MainActivity extends FragmentActivity {
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnLoadFrag1 = (Button) findViewById(R.id.btn_show_fragment1);
        btnLoadFrag1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                Fragement1 fragment1 = new Fragement1();
                transaction.add(R.id.fragment_container, fragment1);
                transaction.commit();
            }
        });

        Button btnLoagFrag2 = (Button)findViewById(R.id.btn_show_fragment2);
        btnLoagFrag2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                Fragement2 fragment2 = new Fragement2();
                transaction.add(R.id.fragment_container, fragment2);
                transaction.commit();
            }
        });
    }
}

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章