Android(Activity創(chuàng)建渴庆,跳轉(zhuǎn)方式,傳值雅镊,生命周期)

一.Activity的創(chuàng)建方式:

A:第一種方式

1.創(chuàng)建一個(gè)類繼承系統(tǒng)的Activity
2.在清單文件中進(jìn)行注冊
注冊方式:在application標(biāo)簽下添加一個(gè)Activity標(biāo)簽襟雷,
          并給其添加name屬性android:name="需要注冊的Activity的完整路徑名"
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        <!--解決屏幕旋轉(zhuǎn)Activity被銷毀重建,且不能保存之前UI狀態(tài)的問題 -->
        android:configChanges="orientation|keyboardHidden|screenSize" 
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <!--新建Activity的注冊 -->
    <activity 
        android:name="com.ljavadroid.day06_activitylifecycle.SectondActivity"
        android:configChanges="orientation|keyboardHidden|screenSize" >
    </activity>
</application>
3.實(shí)現(xiàn)onCreate()方法仁烹,該方法是當(dāng)Acitivity創(chuàng)建時(shí)由系統(tǒng)框架回調(diào)的耸弄。
  該方法中必須要調(diào)用setContentView(R.layout.XXX);方法加載當(dāng)前Activity顯示的布局。
  它也可以接收一個(gè)View.

B.第二種方式

1.導(dǎo)航的方式卓缰,通過向?qū)?chuàng)建Acitivity.File-->new-->other-->Android-->Android Activity
  該種方式會自動(dòng)在清單文件中注冊计呈。

二.Activity之間的跳轉(zhuǎn):

方法1:在構(gòu)造函數(shù)中指定

      Intent:意圖(顯示意圖)砰诵,目的的意思 Intent是Activity界面跳轉(zhuǎn)的橋梁,指定了從原
      Aciticy跳轉(zhuǎn)到目標(biāo)Activity.
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
//啟動(dòng)Activity傳入Intent意圖對象
startActivity(intent);

方法2:用setClass()方法

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

方法3:通過指定組件名稱的方式實(shí)現(xiàn)跳轉(zhuǎn)(可以實(shí)現(xiàn)一個(gè)App跳轉(zhuǎn)到另一個(gè)App)

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

//注意:該方式可以實(shí)現(xiàn)一個(gè)App跳轉(zhuǎn)到另一個(gè)App.(跨應(yīng)用:只能跳轉(zhuǎn)到入口級Activity)
//setClassName(String packageName, String className)方法源碼調(diào)用如下:
public Intent setClassName(String packageName, String className) {
    mComponent = new ComponentName(packageName, className);
    return this;
}
//和ComponetName對應(yīng)的方式setClassName("要跳轉(zhuǎn)到應(yīng)用的完整包名","入口Activity的完整包名+類名");
intent.setClassName("com.ljavadroid.day06_activitypassvalue_intent",
                    "com.ljavadroid.day06_activitypassvalue_intent.MainActivity");

方法四:隱式意圖

隱式意圖的好處:可以跨應(yīng)用啟動(dòng)APP.不需要知道包名和類名捌显。只需要知道Action就可以隱式啟動(dòng)了
應(yīng)用:在網(wǎng)絡(luò)下載的圖片茁彭,如果手機(jī)上同時(shí)有多個(gè)支持打開圖片的應(yīng)用,打開時(shí)會提示你選擇哪個(gè)應(yīng)用扶歪,
通過隱式意圖可以調(diào)用系統(tǒng)應(yīng)用做某些操作理肺。

//1.隱式意圖需要在清單文件意圖過濾器中約定<action name=""/>的內(nèi)容,還有<category name=""/>
<Intent-Filter 
<action android:name="com.qianfeng.day06_createactivity.SecondActivity" />
<category android:name="android.intent.category.DEFAULT"/>
<!--DEFUALT代表當(dāng)前Activity為普通Acitivity-->
/>
//2.Java代碼部分
Intent intent = new Intent();
//com.qianfeng.day06_createactivity.SecondActivity為清單文件中約定的內(nèi)容,通常約定為完整包名+類名.
intent.setAction("com.qianfeng.day06_createactivity.SecondActivity");
//其實(shí)系統(tǒng)默認(rèn)就由這句話 默認(rèn)省略了
//intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);

三.Activity生命周期

1.完整生命周期:onCreate-->onStart-->onResume-->onPause-->onStop-->onDestory
2.可見生命周期: onStart---onStop
3.前臺生命周期:onResume---onPause


image

代碼:

public class MainActivity extends Activity {

    //當(dāng)Activity第一次被創(chuàng)建的時(shí)候回調(diào)的方法善镰,該方法主要做一些初始化的操作妹萨。
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("TAG", "----onCreate----");
    }
    
    //點(diǎn)擊按鈕 頁面跳轉(zhuǎn)
    public void click(View view){
        Intent intent = new Intent(this, OtherActivity.class);
        startActivity(intent);
    }

    /**
     *  當(dāng)前Activity用戶可見的時(shí)候回調(diào)的方法,此時(shí)Activity還沒有完全加載完成炫欺。
     *  在用戶操交互之前的一些操作事件可以在這里操作乎完,如對網(wǎng)絡(luò)連接的檢查。
    **/
    @Override
    protected void onStart() {
        super.onStart();
        Log.i("TAG", "----onStart----");
    }

    //當(dāng)Activity獲取用戶焦點(diǎn)時(shí)回調(diào)的方法(Activity能夠與用戶進(jìn)行交互)
    @Override
    protected void onResume() {
        super.onResume();
        Log.i("TAG", "----onResume----");
    }

    //當(dāng)Activty失去用戶焦點(diǎn)的時(shí)候回調(diào)的方法(Activity不能與用戶交互)
    @Override
    protected void onPause() {
        super.onPause();
        Log.i("TAG", "----onPause----");
    }

    /**
    * 當(dāng)Activty用戶不可見的時(shí)候回調(diào)的方法
    * 在這里監(jiān)聽后臺事件的狀態(tài)竣稽,一旦狀態(tài)完成囱怕,如下載完成
    * 當(dāng)Activity重新回到可見時(shí)霍弹,提示用戶UI改變的狀態(tài)毫别,通過發(fā)廣播的方式
    * 提示用戶下載完成的通知。
    **/
    @Override
    protected void onStop() {
        super.onStop();
        Log.i("TAG", "----onStop----");
    }

    //當(dāng)Activity重新變成用戶可見的時(shí)候回調(diào)的方法
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("TAG", "----onRestart----");
    }

    //當(dāng)Activity被銷毀的時(shí)候回調(diào)的方法
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "----onDestroy----");
    }
}
//通過兩個(gè)Activity之間的切換來觀察生命周期各個(gè)方法是在什么時(shí)候調(diào)用的
public class OtherActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other);
        Log.i("TAG", "OtherActivity:---onCreate----");
    }

    //當(dāng)前Activity用戶可見的時(shí)候回調(diào)的方法
    @Override
    protected void onStart() {
        super.onStart();
        Log.i("TAG", "OtherActivity:---onStart----");
    }

    //當(dāng)Activity獲取用戶焦點(diǎn)時(shí)回調(diào)的方法(Activity能夠與用戶進(jìn)行交互)
    @Override
    protected void onResume() {
        super.onResume();
        Log.i("TAG", "OtherActivity:----onResume----");
    }

    //當(dāng)Activty失去用戶焦點(diǎn)的時(shí)候回調(diào)的方法(Activity不能與用戶交互)
    @Override
    protected void onPause() {
        super.onPause();
        Log.i("TAG", "OtherActivity:----onPause----");
    }

    //當(dāng)Activty用戶不可見的時(shí)候回調(diào)的方法
    @Override
    protected void onStop() {
        super.onStop();
        Log.i("TAG", "OtherActivity:----onStop----");
    }

    //當(dāng)Activity重新變成用戶可見的時(shí)候回調(diào)的方法
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("TAG", "OtherActivity:----onRestart----");
    }

    //當(dāng)Activity被銷毀的時(shí)候回調(diào)的方法
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "OtherActivity:----onDestroy----");
    }
}

四.Activity傳值

1.用Intent實(shí)現(xiàn)Activity之間的傳值:

注意:如果甲頁面使用putExtras()方式傳值典格,那么乙頁面使用getExtras()接收值岛宦;
如果甲頁面使用的是putExtra(bundle)方法傳值,乙頁面使用getBundleExtra()接收值耍缴。

//傳值的方式一:直接使用intent對象
Intent intent = new Intent(MainActivity.this, OtherActivity.class);

intent.putExtra("Name", "張欣");
intent.putExtra("Sex", "男");
intent.putExtra("Age", 18);
intent.putExtra("isMarried", true);

//傳值方式二:通過Bundle傳遞數(shù)據(jù)砾肺,底層數(shù)據(jù)結(jié)構(gòu)為ArrayMap(建議使用該種方式)
Bundle bundle = new Bundle();
//將傳遞的數(shù)據(jù)放入bundle
bundle.putString("Name","趙四");
bundle.putString("Sex","男");
bundle.putInt("Age",32);

//將攜帶數(shù)據(jù)的bundle作為intent的參數(shù)傳遞
intent.putExtras(bundle);

//也可將bundle以Key,value的形式作為intent的參數(shù)傳遞
intent.putExtra("BundleKey",bundle);

//最后是啟動(dòng)Activity
startActivity(intent);

在OtherActivity里取值

//先得到傳遞過來的Intent對象
Intent intent = getIntent();

//取出數(shù)據(jù)-->對應(yīng)傳值方式一
String name = intent.getStringExtra("Name");
String sex = intent.getStringExtra("Sex");
int age = intent.getIntExtra("Age", 20); ?
boolean isMarried = intent.getBooleanExtra("isMarried", false);


//取出bundle里的數(shù)據(jù)-->對應(yīng)傳值方式二
//通過得到的Intent對象獲取bundle
Bundle bundle = intent.getExtras();

//如果bundle是用key,value的方式傳遞過來的防嗡,用如下方式獲取bundle
Bundle bundle = intent.getBundleExtra("BundleKey");

String name = bundle.getString("Name");
String sex = bundle.getString("Sex");
int age = bundle.getInt("Age");
boolean isMarried = bundle.getBoolean("isMarried");

//最后可通過Toast顯示數(shù)據(jù)变汪,或用TextView來接收數(shù)據(jù)并展示
Toast.makeText(OtherActivity.this,
"name="+name+",sex="+sex+",age="+age+",
isMarried="+isMarried, Toast.LENGTH_SHORT).show();

二.通過application來傳值

步驟:
1.創(chuàng)建Application的子類,將需要進(jìn)行全局存儲的內(nèi)容聲明為這個(gè)類的屬性蚁趁; 并且提供公共訪問set get方法裙盾,即將需要存儲的數(shù)據(jù)作為application的屬性。

2.在源Activity中通過getApplication方法得到全局的對象他嫡,,然后調(diào)用setXXX方 法設(shè)置值番官。

3.目標(biāo)Activity通過getApplication方法得到全局對象,然后調(diào)用getXXX方法取出 已經(jīng)存儲好的值

4.將Application子類的全局對象在清單配置文件中注冊(==關(guān)鍵钢属,不要忘了==)
如果不注冊將會報(bào)ClassCastException

==注:Application 里存儲的全局變量在當(dāng)前項(xiàng)目的每個(gè)Activity中都可以獲取徘熔, 也可重新設(shè)置里面的值==

.Application對象的生命周期是整個(gè)程序中最長的,它的生命周期就等于這個(gè)程序的生命周期淆党。因?yàn)樗侨值膯卫目崾Γ栽诓煌腁ctivity,Service中獲得的對象都是同一個(gè)對象讶凉。所以可以通過Application來進(jìn)行一些,如:數(shù)據(jù)傳遞山孔、數(shù)據(jù)共享和數(shù)據(jù)緩存等操作缀遍,==Application里面的onCreate()方法才是真正的Android程序的入口。==

.Application和Activity,Service一樣是Android框架的一個(gè)系統(tǒng)組件饱须,當(dāng)Android程序啟動(dòng)時(shí)系統(tǒng)會創(chuàng)建一個(gè)Application對象域醇,用來存儲系統(tǒng)的一些信息

應(yīng)用場景:
在Android中,可以通過繼承Application類來實(shí)現(xiàn)應(yīng)用程序級的全局變量蓉媳,這種全局變量方法相對靜態(tài)類更有保障譬挚,直到應(yīng)用的所有Activity全部被destory掉之后才會被釋放掉。

代碼:
說明:就是想看看每個(gè)Activity對Application里全局變量的獲取和設(shè)置

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

        MyApplication myApplication = (MyApplication)this. getApplication();
        //獲取Application全局變量值酪呻,看是否初始化
        Log.i("TAG", "MainActivity---------->修改前currentIndex:"+myApplication.getCurrentIndex());
        Log.i("TAG", "MainActivity---------->修改前value:"+myApplication.getValue());

        //重新通過MainAcitivy重新設(shè)置初始值:
        myApplication.setCurrentIndex(26);
        myApplication.setValue("Jhon");

        //再次獲取進(jìn)程中的全局變量值减宣,看是否被修改
        Log.i("TAG", "MainActivity---------->修改后currentIndex:"+myApplication.getCurrentIndex());
        Log.i("TAG", "MainActivity---------->修改后value:"+myApplication.getValue());
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "MainActivity---被銷毀了");
    }
    //點(diǎn)擊按鈕跳轉(zhuǎn)到secondactivity
    public void toSecondActivity(View view){
        //跳轉(zhuǎn)
        Intent intent = new Intent();
        ComponentName componentName = new ComponentName(MainActivity.this, SecondActivity.class);
        intent.setComponent(componentName);
        startActivity(intent);
    }
}
public class SecondActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        //將MyApplication 中的值取出來
        MyApplication myApplication = (MyApplication) getApplication();
        //獲取全局值
        Log.i("TAG", "SecondActivity----->"+myApplication.getCurrentIndex());
        Log.i("TAG","SecondActivity------>"+myApplication.getValue());

        //通過SecondActivity重新設(shè)置初始值:
        myApplication.setCurrentIndex(88);
        myApplication.setValue("Summer");

        //再次獲取進(jìn)程中的全局變量值,看是否被修改
        Log.i("TAG", "SecondActivity---------->修改后currentIndex:"+myApplication.getCurrentIndex());
        Log.i("TAG", "SecondActivity---------->修改后value:"+myApplication.getValue());
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "SecondActivity--->被銷毀了");
    }
    //點(diǎn)擊按鈕跳轉(zhuǎn)到thirdActivity
    public void toThirdActivity(View view){
        Intent intent = new Intent();
        intent.setClass(SecondActivity.this, ThirdActivity.class);
        startActivity(intent);
    }
}
public class ThirdActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        
        MyApplication myApplication = (MyApplication) getApplication();
        Log.i("TAG", "ThirdActivity--->currentIndex:"+myApplication.getCurrentIndex());
        Log.i("TAG", "ThirdActivity--->value:"+myApplication.getValue());
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "ThirdActivity--->被銷毀了");
    }
    //去MainActivity
    public void toMainActivity(View view){
        Intent intent = new Intent(ThirdActivity.this,MainActivity.class);
        startActivity(intent);
    }
}

三.靜態(tài)方法傳值:

1.設(shè)置一個(gè)類玩荠,將需要傳遞的屬性封裝成靜態(tài)的,并生成靜態(tài)的set get 方法.

2.通過靜態(tài)方法傳值

Intent intent = new Intent(MainActivity.this,XXX.class);
//通過類名.set()或類名.get()來設(shè)置和獲取值
Person.setName("James");
startActivity(intent);

3.取值

String name = Person.getName();

四.通過Activity傳遞一個(gè)對象

1.創(chuàng)建需要傳遞的實(shí)體對象漆腌,并實(shí)現(xiàn)Serializable接口,封裝好類的屬性和set/get方法阶冈。

2.在原Activity中通過 new 一個(gè)該類的對象的方式闷尿,用set方法設(shè)置類的屬性值。將對象作為Intent的參數(shù)傳遞給目標(biāo)Activity女坑。
intent.putExtra("Person",person);
startActivity(intent);

3.在目標(biāo)Activity中接收對象
//獲取Intent 的實(shí)例
Intent intent = getIntent();
Person person = (Person) intent.getSerializableExtra("Person");
person.getName();

代碼:

public class MainActivity extends Activity {
    private Button button;
    private EditText editText_name,editText_age;    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText_name = (EditText) findViewById(R.id.editText_name);
        editText_age = (EditText) findViewById(R.id.editText_age);
        button = (Button) findViewById(R.id.button);
        
        //點(diǎn)擊按鈕需要做什么填具?從EditText中取出用戶輸入的內(nèi)容 將其封裝到對象中 把對象傳遞過去
    button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String name = editText_name.getText().toString().trim();
        String age = editText_age.getText().toString().trim();
        
        //封裝到對象中
        Person person = new Person();
        person.setName(name);
        person.setAge(age);
        
        Intent intent = new Intent(MainActivity.this, OtherActivity.class);
        intent.putExtra("Person", person);
        startActivity(intent);
           }
        });
    }
}
public class OtherActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other);
        
        Intent intent = getIntent();
        Person person = (Person) intent.getSerializableExtra("Person");
        
        Toast.makeText(this, person.getName()+","+person.getAge(), Toast.LENGTH_LONG).show();
    }
}

public class Person implements Serializable{
    private String name;
    private String age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
}

五.接收目標(biāo)Activiy回傳值

代碼:

public class MainActivity extends Activity {
    private EditText editText1,editText2,editText3;
    private Button button;
    private static final int REQUEST_CODE=1;//請求的請求碼

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        initView();
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String number1 = editText1.getText().toString();
                String number2 = editText2.getText().toString();
                Intent intent = new Intent(MainActivity.this, OtherActivity.class);
                intent.putExtra("Number1", number1);
                intent.putExtra("Number2", number2);
                //如果啟動(dòng)的目標(biāo)Activity需要回傳結(jié)果需要使用startActivityForResult
                startActivityForResult(intent, REQUEST_CODE);
            }
        });
    }
    private void initView() {
        editText1 = (EditText) findViewById(R.id.editText1);
        editText2 = (EditText) findViewById(R.id.editText2);
        button = (Button) findViewById(R.id.button);
        editText3 = (EditText) findViewById(R.id.editText3);
    }

    //重寫該方法處理回傳的結(jié)果
    /**
     * requestCode:請求碼 startActivityForResult指定 用來標(biāo)示請求的整數(shù)
     * resultCode:結(jié)果碼  setResult()指定 用于標(biāo)識結(jié)果的整數(shù)
     * data: 結(jié)果界面通過調(diào)用setResul()回傳的intent對象
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == -1) {
            String result = data.getStringExtra("result");
            editText3.setText(result);
        }
    }
}
public class OtherActivity extends Activity {
    private EditText editText1_result,editText2_result,editText3_result;
    private Button button_result;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other);
        initView();
        Intent intent = getIntent();
        String number1 = intent.getStringExtra("Number1");
        String number2 = intent.getStringExtra("Number2");
        editText1_result.setText(number1);
        editText2_result.setText(number2);
        
        //點(diǎn)擊按鈕做什么? 獲取結(jié)果然后回傳給源Activity
        button_result.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                String result = editText3_result.getText().toString();
                Intent intent = new Intent();
                intent.putExtra("result",result);
                setResult(Activity.RESULT_OK, intent);//將結(jié)果存儲到intent當(dāng)中并進(jìn)行回傳
                OtherActivity.this.finish();//表示銷毀當(dāng)前的Activity
            }
        });
    }

    private void initView() {
        editText1_result = (EditText) findViewById(R.id.editText1_result);
        editText2_result = (EditText) findViewById(R.id.editText2_result);
        button_result = (Button) findViewById(R.id.button_result);
        editText3_result = (EditText) findViewById(R.id.editText3_result);
    }
}

六.Intent的七大屬性:

A.作用:
1.啟動(dòng)應(yīng)用程序組件
2.啟動(dòng)系統(tǒng)的應(yīng)用組件
3.可以在啟動(dòng)組件的同時(shí)傳遞數(shù)據(jù)
B.七大屬性:ComponentName--Action--Category--Data--Type--Extra--Flag
代碼:

/**
 * Intent7大屬性
 * uri 指定我們要打開文件的路徑
 * type:要打開或者播放的文件的文件類型  MIME類型
 * audio/mp3
 * @author Administrator
 *
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("TAG", "MainActivity對象="+MainActivity.this);
        Log.i("TAG", "---SD卡"+Environment.getExternalStorageDirectory());
        Log.i("TAG","------sd卡"+Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
        
    }

    public void click(View view){
        Intent intent = new Intent();
        switch (view.getId()) {
        case R.id.button1:
            
            // 通過這種方式可以先實(shí)現(xiàn)從一個(gè)App跳轉(zhuǎn)到另一個(gè)App(只能跳轉(zhuǎn)到入口級Activity) 源碼中調(diào)用componentName
            intent.setClassName("com.qianfeng.day06_createactivity", "com.qianfeng.day06_createactivity.SecondActivity");
//          ComponentName componentName = new ComponentName(MainActivity.this, NextActivity.class);
//          intent.setComponent(componentName);
            
//          上面的寫法被簡化成以下的寫法,也就是說平時(shí)使用的Intent頁面跳轉(zhuǎn)都是顯示意圖
//          Intent intent2 = new Intent(MainActivity.this, NextActivity.class);
            break;
        case R.id.button2:
            intent.setAction("com.qianfeng.day07_intent7.NextActivity");
            break;
            
        case R.id.button3://返回手機(jī)主屏幕
            intent.setAction(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            break;
            
        case R.id.button4:
            //直接呼叫Data中攜帶的電話號碼
            //Url:統(tǒng)一資源定位符匆骗,Url是Uri的一個(gè)子集   Uri:統(tǒng)一資源標(biāo)示符
            intent.setAction(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel://10086"));//將字符串電話號碼轉(zhuǎn)換成Uri的格式
            break;
            
        case R.id.button5://顯示撥號面板
            intent.setAction(Intent.ACTION_DIAL);
            intent.setData(Uri.parse("tel://10086"));
            break;
        case R.id.button6://打開瀏覽器
            intent.setAction(Intent.ACTION_VIEW);
            intent.setData(Uri.parse("http://www.baidu.com"));
            break;
            
        case R.id.button7://打開設(shè)置界面
            intent.setAction("android.settings.SETTINGS");
            break;
        
        case R.id.button8://打開WiFi設(shè)置界面
            intent.setAction("android.settings.WIFI_SETTINGS");
        
        case R.id.button9://打開聯(lián)系人界面
            intent.setAction("com.android.contacts.action.LIST_CONTACTS");
            break;
            
        case R.id.button10://發(fā)送短信
            intent.setAction(Intent.ACTION_SENDTO);
            intent.setData(Uri.parse("smsto://5554"));
            intent.putExtra("sms_body", "快點(diǎn)下課吧劳景!");//鍵的名稱一定要是sms_body
            break;
            
        case R.id.button11://打開圖片
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File("/storage/sdcard/android.jpg")), "image/*");
            break;
            
        case R.id.button12://打開音頻
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File("/storage/sdcard/xxx.mp3")), "audio/*");
            break;
        case R.id.button13://打開視頻
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File("/storage/sdcard/xxx.mp4")), "video/*");
            break;
            
        case R.id.button14://打開文本文件
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(new File("/storage/sdcard/hehe.txt")), "text/*");
            break;
            
        case R.id.button15:
            intent.setClass(MainActivity.this, NextActivity.class);
            break;
        
        }
        
        startActivity(intent);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", MainActivity.this+"銷毀了");
    } 
}
public class NextActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_next);
        Log.i("TAG", "NextActivity對象="+NextActivity.this);
    }
    
    public void start(View view){
        Intent intent = new Intent(NextActivity.this, ThirdActivity.class);
        startActivity(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.next, menu);
        return true;
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", NextActivity.this+"銷毀了");
    }
}
public class ThirdActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);
        Log.i("TAG", "ThirdActiviy對象="+ThirdActivity.this);
    }
    
    public void start(View view){
        Intent intent = new Intent(ThirdActivity.this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//相當(dāng)于singleTask
        startActivity(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.third, menu);
        return true;
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TAG", ThirdActivity.this+"銷毀了");
    }
}

來自網(wǎng)絡(luò):Android Application對象必須掌握的六點(diǎn)

作者:皇馬船長

1.Application是什么?

Application和Activity,Service一樣,是android框架的一個(gè)系統(tǒng)組件碉就,當(dāng)android程序啟動(dòng)時(shí)系統(tǒng)會創(chuàng)建一個(gè) application對象盟广,用來存儲系統(tǒng)的一些信息。通常我們是不需要指定一個(gè)Application的瓮钥,這時(shí)系統(tǒng)會自動(dòng)幫我們創(chuàng)建筋量,如果需要?jiǎng)?chuàng)建自己 的Application,也很簡單創(chuàng)建一個(gè)類繼承 Application并在manifest的application標(biāo)簽中進(jìn)行注冊(只需要給Application標(biāo)簽增加個(gè)name屬性把自己的 Application的名字定入即可)骏庸。

2.通過Application傳遞數(shù)據(jù)

假如有一個(gè)Activity A, 跳轉(zhuǎn)到 Activity B ,并需要推薦一些數(shù)據(jù)毛甲,通常的作法是Intent.putExtra() 讓Intent攜帶,或者有一個(gè)Bundle把信息加入Bundle讓Intent推薦Bundle對象具被,實(shí)現(xiàn)傳遞玻募。
但這樣作有一個(gè)問題在 于,Intent和Bundle所能攜帶的數(shù)據(jù)類型都是一些基本的數(shù)據(jù)類型一姿,如果想實(shí)現(xiàn)復(fù)雜的數(shù)據(jù)傳遞就比較麻煩了七咧,通常需要實(shí)現(xiàn) Serializable或者Parcellable接口跃惫。這其實(shí)是Android的一種IPC數(shù)據(jù)傳遞的方法。如果我們的兩個(gè)Activity在同一個(gè) 進(jìn)程當(dāng)中為什么還要這么麻煩呢艾栋,只要把需要傳遞的對象的引用傳遞過去就可以了爆存。基本思路是這樣的蝗砾。在Application中創(chuàng)建一個(gè)HashMap 先较,以字符串為索引,Object為value這樣我們的HashMap就可以存儲任何類型的對象了悼粮。在Activity A中把需要傳遞的對象放入這個(gè)HashMap闲勺,然后通過Intent或者其它途經(jīng)再把這索引的字符串傳遞給Activity B ,Activity B 就可以根據(jù)這個(gè)字符串在HashMap中取出這個(gè)對象了。只要再向下轉(zhuǎn)個(gè)型 扣猫,就實(shí)現(xiàn)了對象的傳遞菜循。

3.Application數(shù)據(jù)緩存

我一般會習(xí)慣在application中建立兩個(gè)HashMap一個(gè)用于數(shù)據(jù)的傳遞,一個(gè)用于緩 存一些數(shù)據(jù)申尤。比如有一個(gè)Activity需要從網(wǎng)站獲取一些數(shù)據(jù)癌幕,獲取完之后我們就可以把這個(gè)數(shù)據(jù)cache到Application 當(dāng)中,當(dāng)頁面設(shè)置到其它Activity再回來的時(shí)候昧穿,就可以直接使用緩存好的數(shù)據(jù)了勺远。但如果需要cache一些大量的數(shù)據(jù),最好是cache一些 (軟引用)SoftReference 粤咪,并把這些數(shù)據(jù)cache到本地rom上或者sd卡上谚中。如果在application中的緩存不存在渴杆,從本地緩存查找寥枝,如果本地緩存的數(shù)據(jù)也不存在再從網(wǎng) 絡(luò)上獲取。

4.PitFalls(漢語:易犯的錯(cuò)誤)

使用Application如果保存了一些不該保存的對象很容易導(dǎo)致內(nèi)存泄漏磁奖。如果在Application的oncreate中執(zhí)行比較 耗時(shí)的操作囊拜,將直接影響的程序的啟動(dòng)時(shí)間。這些清理工作不能依靠onTerminate完成比搭,因?yàn)閍ndroid會盡量讓你的程序一直運(yùn)行冠跷,所以很有可能 onTerminate不會被調(diào)用。

5.MemoryLeak

在Java中內(nèi)存泄漏是只身诺,某個(gè)(某些)對象已經(jīng)不在被使用應(yīng)該被gc所回收蜜托,但有一個(gè)對象持有這個(gè)對象的引用而阻止這個(gè)對象被回收。比如我 們通常會這樣創(chuàng)建一個(gè)View TextView tv = new TextView(this);這里的this通常都是Activity霉赡。所以這個(gè)TextView就持有著這個(gè)Activity的引用橄务。下面看張圖 (Google IO 2011 ppt中抄得)
通常情況下,當(dāng)用戶轉(zhuǎn)動(dòng)手機(jī)的時(shí)候穴亏,android會重新調(diào)用OnCreate()方法生成一個(gè)新的Activity蜂挪,原來的 Activity應(yīng)該被GC所回收重挑。但如果有個(gè)對象比如一個(gè)View的作用域超過了這個(gè)Activity(比如有一個(gè)static對象或者我們把這個(gè) View的引用放到了Application當(dāng)中),這時(shí)候原來的Activity將不能被GC所回收棠涮,Activity本身又持有很多對象的引用谬哀,所以 整個(gè)Activity的內(nèi)存被泄漏了。

1 備注:經(jīng)常導(dǎo)致內(nèi)存泄漏核心原因:
2 keeping a long-lived reference to a Context.持有一個(gè)context的對象严肪,從而gc不能回收史煎。
3 情況如下:
1. 一個(gè)View的作用域超出了所在的Activity的作用域,比如一個(gè)static的View或者把一個(gè)View cache到了application當(dāng)中 etc.理解:內(nèi)存:注意靜態(tài)的數(shù)據(jù)和緩存中的數(shù)據(jù)驳糯;注意釋放劲室。
2.某些與View關(guān)聯(lián)的Drawable的作用域超出了Activity的作用域。
3.Runnable對象:比如在一個(gè)Activity中啟用了一個(gè)新線程去執(zhí)行一個(gè)任務(wù)结窘,在這期間這個(gè)Activity被系統(tǒng)回收了很洋, 但Runnalbe的 任務(wù)還沒有執(zhí)行完畢并持有Activity的引用而泄漏,但這種泄漏一般來泄漏一段時(shí)間隧枫,只有Runnalbe的線程執(zhí)行完閉喉磁,這個(gè) Activity又可以被正常回收了官脓。
4.內(nèi)存類的對象作用域超出Activity的范圍:比如定義了一個(gè)內(nèi)存類來存儲數(shù)據(jù)协怒,又把這個(gè)內(nèi)存類的對象傳給了其它Activity 或者Service等。因?yàn)閮?nèi)部類的對象會持有當(dāng)前類的引用卑笨,所以也就持有了Context的引用孕暇。解決方法是如果不需要當(dāng)前的引用把內(nèi)部類寫成static或者,把內(nèi)部類抽取出來變成一個(gè)單獨(dú)的類赤兴,或者把避免內(nèi)部對象作用域超出Activity的作用域妖滔。out Of Memery Error 在android中每一個(gè)程序所分到的內(nèi)存大小是有限的,如果超過了這個(gè)數(shù)就會報(bào)Out Of Memory Error桶良。 android給程序分配的內(nèi)存大小與手機(jī)硬件有關(guān)座舍,以下是一些手機(jī)的數(shù)據(jù):G1:16M Droid:24 Nexus One:32M Xoom:48Ms所以盡量把程序中的一些大的數(shù)據(jù)cache到本地文件。以免內(nèi)存使用量超標(biāo)陨帆。記得數(shù)據(jù)傳遞完成之后曲秉,把存放在application的HashMap中的數(shù)據(jù)remove掉,以免發(fā)生內(nèi)存的泄漏疲牵。

6:生命周期:

onCreate 在創(chuàng)建應(yīng)用程序時(shí)創(chuàng)建

onTerminate 當(dāng)終止應(yīng)用程序?qū)ο髸r(shí)調(diào)用承二,不保證一定被調(diào)用,當(dāng)程序是被內(nèi)核終止以便為其他應(yīng)用程序釋放資源纲爸,那
么將不會提醒亥鸠,并且不調(diào)用應(yīng)用程序的對象的onTerminate方法而直接終止進(jìn) 程
onLowMemory 當(dāng)后臺程序已經(jīng)終止資源還匱乏時(shí)會調(diào)用這個(gè)方法。好的應(yīng)用程序一般會在這個(gè)方法里面釋放一些不必
要的資源來應(yīng)付當(dāng)后臺程序已經(jīng)終止缩焦,前臺應(yīng)用程序內(nèi)存還不夠時(shí)的情況读虏。
onConfigurationChanged 配置改變時(shí)觸發(fā)這個(gè)方法

備注:application 被殺死的情況分析:
為了決定在內(nèi)存較低的時(shí)候殺掉哪個(gè)進(jìn)程, Android會根據(jù)運(yùn)行在這些進(jìn)程內(nèi)的組件及他們的狀態(tài)把進(jìn)程劃分成一個(gè)”重要程度層次”. 其重要的程度按以下規(guī)則排序:

1:前端進(jìn)程可以是一個(gè)持有運(yùn)行在屏幕最前端并與用戶交互的Activity的進(jìn)程(onResume方法被調(diào)用時(shí))责静,也可以是持有一個(gè)正在運(yùn)行的IntentReceiver(也就是說他正在執(zhí)行自己的onReceiveIntent方法)的進(jìn)程. 在系統(tǒng)中, 只會有少數(shù)這樣的進(jìn)程, 并且除非內(nèi)存已經(jīng)低到不夠這些進(jìn)程運(yùn)行, 否則系統(tǒng)不會主動(dòng)殺掉這些進(jìn)程. 這時(shí), 設(shè)備通常已經(jīng)達(dá)到了需要內(nèi)存整理的狀態(tài), 所以殺掉這些進(jìn)程是為了不讓用戶界面停止響應(yīng).
2:可視進(jìn)程是持有一個(gè)被用戶可見, 但沒有顯示在最前端 (onPause方法被調(diào)用時(shí)) 的Activity的進(jìn)程. 舉例來說, 這種進(jìn)程通常出現(xiàn)在一個(gè)前端Activity以一個(gè)對話框出現(xiàn)并保持前一個(gè)Activity可見時(shí). 這種進(jìn)程被系統(tǒng)認(rèn)為是極其重要的, 并且通常不會被殺掉, 除非為了保持所有前端進(jìn)程正常運(yùn)行不得不殺掉這些可見進(jìn)程.
3:服務(wù)進(jìn)程是持有一個(gè)Service的進(jìn)程, 該Service是由startService()方法啟動(dòng)的, 盡管這些進(jìn)程用戶不能直接看到, 但是通常他們做的工作用戶是十分關(guān)注的(例如, 在后臺播放mp3或是在后臺下載 上傳文件), 所以, 除非為了保持所有的前端進(jìn)程和可視進(jìn)程正常運(yùn)行外, 系統(tǒng)是不會殺掉服務(wù)進(jìn)程的.
4:后臺進(jìn)程是持有一個(gè)不再被用戶可見的Activity(onStop()方法被調(diào)用時(shí))的進(jìn)程. 這些進(jìn)程不會直接影響用戶體驗(yàn). 加入這些進(jìn)程已經(jīng)完整的,正確的完成了自己的生命周期(訪問Activity查看更多細(xì)節(jié)), 系統(tǒng)會在為前三種進(jìn)程釋放內(nèi)存時(shí)隨時(shí)殺掉這些后臺進(jìn)程. 通常會有很多的后臺進(jìn)程在運(yùn)行, 所以這些進(jìn)程被存放在一個(gè)LRU列表中, 以保證在低內(nèi)存的時(shí)候, 最近一個(gè)被用戶看到的進(jìn)程會被最后殺掉.
5:空進(jìn)程是沒有持有任何活動(dòng)應(yīng)用組件的進(jìn)程. 保留這種進(jìn)程的唯一理由是為了提供一種緩存機(jī)制, 縮短他的應(yīng)用下次運(yùn)行時(shí)的啟動(dòng)時(shí)間. 就其本身而言, 系統(tǒng)殺掉這些進(jìn)程的目的是為了在這些空進(jìn)程和底層的核心緩存之間平衡整個(gè)系統(tǒng)的資源.
6.當(dāng)需要給一個(gè)進(jìn)程分類的時(shí)候, 系統(tǒng)會在該進(jìn)程中處于活動(dòng)狀態(tài)的所有組件里掉選一個(gè)重要等級最高作為分類依據(jù). 查看Activity, Service,和IntentReceiver的文檔, 了解每個(gè)組件在進(jìn)程整個(gè)生命周期中的貢獻(xiàn). 每一個(gè)classes的文檔詳細(xì)描述他們在各自應(yīng)用的生命周期中所起得作用.
7.application 的context

1、它描述的是一個(gè)應(yīng)用程序環(huán)境的信息盖桥,即上下文灾螃。

2、該類是一個(gè)抽象(abstract class)類揩徊,Android提供了該抽象類的具體實(shí)現(xiàn)類(后面我們會講到是ContextIml類)腰鬼。

3、通過它我們可以獲取應(yīng)用程序的資源和類塑荒,也包括一些應(yīng)用級別操作熄赡,例如:啟動(dòng)一個(gè)Activity,發(fā)送廣播齿税,接受Intent信息等彼硫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市凌箕,隨后出現(xiàn)的幾起案子拧篮,更是在濱河造成了極大的恐慌,老刑警劉巖牵舱,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件串绩,死亡現(xiàn)場離奇詭異,居然都是意外死亡芜壁,警方通過查閱死者的電腦和手機(jī)礁凡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慧妄,“玉大人顷牌,你說我怎么就攤上這事⊙В” “怎么了韧掩?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長窖铡。 經(jīng)常有香客問我,道長坊谁,這世上最難降的妖魔是什么费彼? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮口芍,結(jié)果婚禮上箍铲,老公的妹妹穿的比我還像新娘。我一直安慰自己鬓椭,他們只是感情好颠猴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布关划。 她就那樣靜靜地躺著,像睡著了一般翘瓮。 火紅的嫁衣襯著肌膚如雪贮折。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天资盅,我揣著相機(jī)與錄音调榄,去河邊找鬼。 笑死呵扛,一個(gè)胖子當(dāng)著我的面吹牛每庆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播今穿,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缤灵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蓝晒?” 一聲冷哼從身側(cè)響起凤价,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拔创,沒想到半個(gè)月后利诺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剩燥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年慢逾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灭红。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侣滩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出变擒,到底是詐尸還是另有隱情君珠,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布娇斑,位于F島的核電站策添,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏毫缆。R本人自食惡果不足惜唯竹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苦丁。 院中可真熱鬧浸颓,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晋涣,卻和暖如春仪媒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姻僧。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工规丽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撇贺。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓赌莺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親松嘶。 傳聞我的和親對象是個(gè)殘疾皇子艘狭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容