java攻城獅之路(Android篇)--Activity生命


一:Activity的激活

1、寫一個類 extends Activity
Activity是android的四大組件之一。
Activity的激活分為顯式意圖激活和隱式意圖激活。
如果一個activity希望別人隱式意圖激活,則要配置過濾器
1 action = "com.shellway.itentab.*"
2 有一個缺省的category,(可以有多個category),若不配置該類型會發生這樣的一個錯誤:Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=cn.itcast.action.main3 }
設置scheme標識如: http:// content:// tel:

隱式意圖激活:就是看要要激活的組件里面的intent-filter,看它是如何編寫要有action,category,data。

配置意圖過濾器就相當於給一個activity取了一個別名。一個activity可以配置多個intent-filter

練習:

package com.shellway.itentab;

import android.support.v7.app.ActionBarActivity;
import android.content.ClipData.Item;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void open(View view){
        switch (view.getId()) {
        case R.id.bt_open1:
            //4種顯式意圖激活方式
            Intent intent1 = new Intent(this,Main2Activity.class);
            //    intent.setClass(this, Main2Activity.class);
            //     intent.setClassName(this, "com.shellway.itentab.Main2Activity");
            //    intent.setClassName("com.shellway.itentab", "com.shellway.itentab.Main2Activity");
            startActivity(intent1);
            break;
        case R.id.bt_open2:
            Intent intent2 = new Intent();
            //設置動作
            intent2.setAction("com.shellway.itent.Main3Activity");
            //設置數據
    //        intent2.setData(Uri.parse("shellway:"));
            //設置類型
    //        intent2.setType("image/jpeg");
            //若設置了類型,它就必須和數據一起設置,分開設置不行
            intent2.setDataAndType(Uri.parse("shellway:"), "image/jpeg");
            startActivity(intent2);
            break;
        case R.id.bt_open3:
            Intent intent3 = new Intent();
            intent3.setAction("android.intent.action.VIEW");
            intent3.setData(Uri.parse("http://www.baidu.com"));
            startActivity(intent3);
            break;
        default:
            break;
        }
        
    }
}
MainActivity.java
package com.shellway.itentab;

import android.app.Activity;
import android.os.Bundle;

public class Main2Activity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
    }
}
Main2Activity.java
package com.shellway.itentab;

import android.app.Activity;
import android.os.Bundle;

public class Main3Activity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
    }
}
Main3Activity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
     >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="這是第一個activity" />
    <Button 
        android:id="@+id/bt_open1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="open"
        android:text="顯示意圖激活"
        />
    <Button android:id="@+id/bt_open2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="open"
        android:text="隱式意圖激活"
        />
    <Button android:id="@+id/bt_open3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="open"
        android:text="打開瀏覽器"
        />

</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
         android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="顯式意圖激活"
        />

</LinearLayout>
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="隱式意圖激活"
        />
    

</LinearLayout>
activity_main3.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shellway.itentab"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <!-- 第一個activity  -->
        <activity
            android:name=".MainActivity"
            android:label="第一個activity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 第二個activity 顯式激活-->
        <activity android:name=".Main2Activity" android:label="第二個activity" />
        <!-- 第三個activity 隱式激活 -->
        <activity android:name=".Main3Activity" android:label="第三個activity">
            <intent-filter >
                <action android:name="com.shellway.itent.Main3Activity" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="shellway"  android:mimeType="image/jpeg" />
            </intent-filter>
        </activity>
        
    </application>

</manifest>
AndroidMainfest.xml

運行結果截圖:

 二:Activity之間的數據傳輸(通過Intent)

1、Bundle 其實是對應HashMap的封裝。該類本身實現了Parceleable接口。
同樣,我們這里寫一個Person類實現Parcelable接口,然后用intent.putExtra(String name, Parcelable value)
和intent.getParcelableExtra(String name)方法來分別存、取對象。

練習(三種數據傳輸方式):

package com.shellway.domain;

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {

    private int id;
    private String name;
    private int age;
    
    @Override
    public int describeContents() {
        return 0;
    }
    
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        //這里的數據的讀取順序要與聲明時的一直
        dest.writeInt(id);
        dest.writeString(name);
        dest.writeInt(age);
    }
    public static final Parcelable.Creator<Person> CREATOR
       = new Parcelable.Creator<Person>() {
        public Person createFromParcel(Parcel in) {
          //這里返回的是下面帶參的出事化后的Person類
          return new Person(in);
    }

    public Person[] newArray(int size) {
      return new Person[size];
    }
  };
    //這里的數據的初始化順序要與聲明時的一直
    public Person(Parcel in){
       id = in.readInt();
       name = in.readString();
       age = in.readInt();
 }

    public Person(int id, String name, int age) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}
Person.java
package com.shellway.passdata;

import com.shellway.domain.Person;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends ActionBarActivity {

    private EditText et_username;
    private EditText et_password;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲得用戶輸入的數據
        et_username = (EditText) findViewById(R.id.et_username);
        et_password = (EditText) findViewById(R.id.et_password);
    }
    public void enter(View view){
        String username = et_username.getText().toString();
        String password = et_password.getText().toString();
        //應用內部的數據傳輸是通過intent來傳輸的,它相當於網頁中的request對象。
        Intent intent = new Intent(this,ReceiveDataActivity.class);
    //  1、傳輸數據的第一種方式
    //    intent.putExtra("username", username);
    //    intent.putExtra("password", password);
    //  2、傳輸數據第二種方式        
        Bundle bundle = new Bundle();
        bundle.putString("username", username);
        bundle.putString("password", password);
        intent.putExtras(bundle);
    //    3、傳輸數據第三種方式,傳輸對象類型數據.
        Person person = new Person(100,"shellway",25);
        intent.putExtra("person", person);
        //這里是顯式激活ReceiveDataActivity
        startActivity(intent);
    }
}
MainActivity.java
package com.shellway.passdata;

import com.shellway.domain.Person;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class ReceiveDataActivity extends Activity {
     @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.receive_data);
        TextView tv_receive = (TextView) findViewById(R.id.tv_receive);
      //獲得從上一個activity傳過來的數據,誰激活我這個activity就從那個activity傳過來。
        Intent intent = getIntent();
      //從intent對象中拿到數據    
    //    String username = intent.getStringExtra("username");
    //    String password = intent.getStringExtra("password");
        
        Bundle bundle = intent.getExtras();
        String username = bundle.getString("username");
        String password = bundle.getString("password");
        
        Person person = intent.getParcelableExtra("person");
        
      //把數據設置到界面上
        tv_receive.setText("用戶名:"+username+",密    碼:"+password 
                                  +"   \n對象:"+person.toString());
    }
}
ReceiveDataActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="用戶名" />
    <EditText 
        android:id="@+id/et_username"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入用戶名"
        />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="密碼" />
    <EditText 
        android:id="@+id/et_password"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入密碼"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="enter"
        android:text="進入"
        />

</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView 
         android:id="@+id/tv_receive"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
        />

</LinearLayout>
receive_data.xml

運行結果截圖:

2、打開一個Activity返回結果:

分析:

package com.shellway.getdataforresult;

import android.support.v7.app.ActionBarActivity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

    private EditText data;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        data = (EditText) findViewById(R.id.et_data);
    }

   public void get(View view){
       Intent intent = new Intent(this,MainActivity2.class);
       //參數100為請求碼,標識請求數據來源
       startActivityForResult(intent, 100);
   }
   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        String name = intent.getStringExtra("name");
        if (requestCode==100) {
            if (intent!=null) {
                data.setText(name);
            }
        }else{
            Toast.makeText(this, "獲取數據失敗", Toast.LENGTH_SHORT).show();
        }
    }
   //若用戶在此activity點擊返回鍵,就finish()
   @Override  
   public boolean onKeyDown(int keyCode, KeyEvent event)  
   {  
       if (keyCode == KeyEvent.KEYCODE_BACK )  
       {  
           // 創建退出對話框  
           AlertDialog isExit = new AlertDialog.Builder(this).create();  
           // 設置對話框標題  
           isExit.setTitle("系統提示");  
           // 設置對話框消息  
           isExit.setMessage("確定要退出嗎");  
           // 添加選擇按鈕並注冊監聽  
           isExit.setButton2("取消", listener);  
           isExit.setButton("確定", listener);  
           // 顯示對話框  
           isExit.show();  
       }  
       return false;  
   }  
   /**監聽對話框里面的button點擊事件*/  
   DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener()  
   {  
       public void onClick(DialogInterface dialog, int which)  
       {  
           switch (which)  
           {  
           case AlertDialog.BUTTON_POSITIVE:// "確認"按鈕退出程序  
               android.os.Process.killProcess(android.os.Process.myPid());    //獲取PID 
               System.exit(0); 
               break;  
           case AlertDialog.BUTTON_NEGATIVE:// "取消"第二個按鈕取消對話框  
               break;  
           default:  
               break;  
           }  
       }  
   }; 
}
MainActivity.java
package com.shellway.getdataforresult;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity2 extends Activity {
    private ListView lv;
    private MyBaseAdapter myBaseAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        
        myBaseAdapter = new MyBaseAdapter();
        
        lv = (ListView) findViewById(R.id.lv_data);
        lv.setAdapter(myBaseAdapter);
        lv.setOnItemClickListener(new MyOnItemClickListener());
    }
    private class MyOnItemClickListener implements OnItemClickListener{

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            String name =  (String) myBaseAdapter.getItem(position);
            Intent intent = new Intent();
            intent.putExtra("name", name);
            //參數200為結果碼,標識返回結果數據來源
            setResult(200, intent);
            finish();
        }
    }
    
    private class MyBaseAdapter extends BaseAdapter{
        String[] data = new String[]{"趙高","劉邦","項羽","楚南公","葛聶"};
        @Override
        public int getCount() {
            return data.length;
        }

        @Override
        public Object getItem(int position) {
            return data[position];
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tv = new TextView(getApplicationContext());
            tv.setTextSize(25);
            tv.setTextColor(Color.BLUE);
            tv.setText(data[position]);
            return tv;
        }
    }
    //若用戶在此界面直接按返回鍵,則結束自己 重新開啟上一個界面
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            Intent myIntent = new Intent();
            myIntent = new Intent(MainActivity2.this, MainActivity.class);
            startActivity(myIntent);
            this.finish();
        }
        return super.onKeyDown(keyCode, event);
    }
}
MainActivity2.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="獲取的數據:" />
    <EditText 
        android:id="@+id/et_data"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="get"
        android:text="獲取"
        />

</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <ListView 
        android:id="@+id/lv_data"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        ></ListView>

</LinearLayout>
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shellway.getdataforresult"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
    <uses-permission android:name="android.permission.RESTART_PACKAGES"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            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 android:name=".MainActivity2" android:label="數據列表"/>
    </application>

</manifest>
AndroidManifest.xml

點擊獲取后的結果截圖:

三、Activity的作用:
起顯示作用,他是用來和用戶交互的。也是一個view的容器
1 完整的生命周期:
onCreate() --> onStart() --> onResume() activiyt已經正常顯示
點擊回退鍵
onPause() --> onStop() --> onDetroy()

2、可視的生命周期
onCreate() --> onStart() --> onResume() activiyt已經正常顯示
打開一個activity。該activity完全覆蓋上一個activity
onPause() ---> onStop()
點擊回退鍵
onRestart() --> onStart() ---> onResume()
點擊回退鍵
onPause() --> onStop() --> onDetroy()

3、前台生命周期
首先把第二個Activity配置:android:theme="@android:style/Theme.Dialog"
就可以把activity變成對話框的效果,注意:如果在一個Activity中彈出對話框,則不會執行任何一個方法。
onCreate() --> onStart() --> onResume() activiyt已經正常顯示
打開一個activity。該activity沒有完全覆蓋上一個activity
onPause()
點擊回退鍵
onResume()

橫豎屏切換的時候:
豎屏到橫屏:activity首先被銷毀,在創建一個新的activity
橫屏到豎屏:activity首先被銷毀,再創建一個新的activity,再把該activity銷毀,再創建一個新的activity.(是由於輸入法的影響)

生命周期代碼:

package com.shellway.lifecycle;

import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends ActionBarActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i(TAG, " onCreate ");
        
    }
    
    public void open1(View view){
        Intent intent = new Intent(this,MainActivity.class);
        startActivity(intent);
    }
    public void open2(View view){
        Intent intent = new Intent(this,Main2Activity.class);
        startActivity(intent);
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, " onStart ");
    }
    
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, " onRestart ");
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, " onResume ");
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, " onPause ");
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, " onStop ");
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, " onDestroy ");
    }
    
}
MainActivity.java
package com.shellway.lifecycle;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class Main2Activity extends Activity {
     private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
    }
     
     public void open1(View view){
        Intent intent = new Intent(this,MainActivity.class);
        startActivity(intent);
    }
     
    public void open2(View view){
        Intent intent = new Intent(this,Main2Activity.class);
        startActivity(intent);
    }
}
Main2Activity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

   <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="open1"
       android:text="打開A界面"
       />
   <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="open2"
       android:text="打開B界面"
       />

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

   <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="open1"
        android:text="打開A界面"
       />
   <Button 
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:onClick="open2"
        android:text="打開B界面"
       />

</LinearLayout>
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shellway.lifecycle"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="第一個Activity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Main2Activity" android:label="第二個Activity" 
                  android:theme="@android:style/Theme.Dialog"/>
    </application>

</manifest>
AndroidManifest.xml

4、任務棧task、進程Process 

task的作用:就是用來管理activity的進入,退出。記錄了用戶的行為。
位於任務棧棧頂的activity就是和用戶交互的。
任務棧里面存放的是:activity的引用

下面詳細介紹activity的四種啟動模式:

1、standard
    standard模式是默認的啟動模式,不用為<activity>配置android:launchMode屬性即可,當然也可以指定值為standard。
    standard模式是所啟動的Activity都是在同一個task容器棧下,不會重新創建新的task容器棧。先壓入棧的Activity實例按順序入棧底,后入棧在棧頂,處於棧的頂部Activity實例處於活動狀態,其他處於非活動狀態。按物理返回鍵,退出當前所處活動狀態Activity窗口,這樣就會從task容器棧中彈出,顯示在手機主屏幕上,從而,有非活動狀態轉換成活動的狀態。其次,standard容器棧可能會存在着相同的Activity實例,只有沒調用一次startActivity方法,就會創建目標Activity實例對象壓入task容器棧。

2、singleTop
    AndroidManifest.xml文件中<activity>launchmode屬性配置singletop,那么啟動實例化Activity,如果task容器棧頂存在已經激活的Activity實例,就會重用當前棧頂的Activity實例,不會再重新去實例化Activity對象。善於思考的朋友可能會問,如果要啟動的目標Activity已經有實例化對象存在task容器棧里面,只是現在不處於棧頂,這樣情況下,singletop啟動模式會創建目標Activity實例嗎?答案是肯定的。要啟動的目標Activity實例正好處於棧頂,才能重用該實例,其他情況必須創建新實例。

 

3、singleTask
singletask模式,特別需要注意了。啟動的目標Activity實例如果已經存在task容器棧中,不管當前實例處於棧的任何位置,是棧頂也好,棧底也好,還是處於棧中間,只要目標Activity實例處於task容器棧中,都可以重用該Activity實例對象,然后,把處於該Activity實例對象上面全部Activity實例清除掉,並且,task容器棧中永遠只有唯一實例對象,不會存在兩個相同的實例對象。所以,如果你想你的應用不管怎么啟動目標Activity,都只有唯一一個實例對象,就使用這種啟動模式。

 

4、singleInstance
singleInstance啟動模式,簡單說就是可以共享某個Activity。比如,應用1的任務容器棧中創建了MainActivity實例,應用2也要激活MainActivity,則不需要創建MainActivity實例,直接可以公用MainActivity實例。尤其值得注意:應用1啟動MainActivity,按home鍵;打開應用2啟動應用1的MainActivity實例。在按home鍵,打開應用1,這時候應用1的界面是應該是處於MainActivity界面實例。

5、理解一些概念
進程:是一個應用程序運行的空間。一個android應用就是一個進程。進程就有他自己的內存空間。
一個進程里面可以有多個線程。在兩個進行之間進行切換是非常好性能。
線程:一個控件單元。
一個task可以對應多個進程。
每個activity的實例是運行在自己的進程里面。
activity程序默認是一個單獨的線程里面來運行。onCreate() 按鈕點擊回調事件、對於顯示的操作都是在主線程里面運行即:UI線程。對於那些耗時的操作不適宜放在主線程里面執行,比如
聯網獲取數據、大文件的拷貝,都需要放置在子線程來操作。
在子線程里執行耗時操作后獲得數據后要更新主界面,可以通過消息機制來解決,因為只有主線程才能對顯示進行操作。,否則會報一下錯誤:
08-29 08:07:41.200: E/AndroidRuntime(1327):
android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Handler :用於子線程和主線程之前的通信。
采用是就消息模式,當子線程完成操作,給主線程發送消息。讓主線程來處理顯示的更新。
子線程和主線程之前的通信練習:

package com.shellway.changeview;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

    protected static final int CHANGE_UI = 0;
    private TextView tv;
    
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case CHANGE_UI:
                int i = (Integer) msg.obj;
                tv.setText(i+"");//設置顯示信息,注意是String類型
                break;
            default:
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv_number);
    }
    
    public void add(View view){
        new Thread(){
            public void run() {
                int i = 0;
                while (i<20) {
                    i = i + 1;
                    SystemClock.sleep(300);//每0.3秒執行一次
                    //創建一個消息對象來傳遞數據
                    Message msg = new Message();
                    //標識消息對象類型
                    msg.what = CHANGE_UI;
                    //封裝數據到消息對象
                    msg.obj = i;
                    //發送消息對象
                    handler.sendMessage(msg);
                }
            };
        }.start();
    }
}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
     >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="自動增加的數據:" />
    <TextView
        android:id="@+id/tv_number"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="0" />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="add"
        android:text="增加"
        />
    

</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shellway.changeview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="子線程通過消息更新界面數據" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
AndroidManifest.xml

運行結果截圖:

6:五種對話框
對話框的創建采用的是構建器模式:

package com.shellway.mydialog;

import android.support.v7.app.ActionBarActivity;
import android.text.AlteredCharSequence;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    /**普通對話框
     * 步驟: 1、創建構建器
     *     2、給構建器設置屬性: 標題 、內容、按鈕
     *     3、創建dialog
     *     4、顯示對話框
     */
    public void generalDialog(View view){
          //創建構建器
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setCancelable(false);//使物理回退鍵失效
          builder.setTitle("shellway的博客");
          builder.setMessage("你會經常來看我的博客嗎?");
          //設置按鈕監聽事件
          builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                
            }
          });
          //設置按鈕監聽事件
          builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            
            @Override
            public void onClick(DialogInterface dialog, int which) {
                
            }
          });
          
          //創建dialog,並顯示
          Dialog dialog = builder.create();
          dialog.show();
    }
    
    //選擇對話框
    public void selectedDialog(View view){
          final String[] items = new String[]{"公子扶蘇","李斯","張良"};
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setCancelable(false);//使物理回退鍵失效
          builder.setTitle("shellway的博客");
          //設置點擊監聽事件
          builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], 0).show();
            }
          });
          
          //創建dialog,並顯示
          Dialog dialog = builder.create();
          dialog.show();
    }
    
    //單選對話框
    public void singleChoiceDialog(View view){
          final String[] items = new String[]{"公子扶蘇","李斯","張良"};
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setCancelable(false);//使物理回退鍵失效
          builder.setTitle("shellway的博客");
          //設置點擊監聽事件
          builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(getApplicationContext(), items[which], 0).show();
            }
          });
          //設置確定按鈕監聽事件
          builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
            }
          });
          
          //創建dialog,並顯示
          Dialog dialog = builder.create();
          dialog.show();
    }
    
    //多選對話框
    public void multiChoiceDialog(View view){
          final String[] items = new String[]{"公子扶蘇","李斯","張良"};
          final boolean[] flag = new boolean[]{true,false,false};
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setCancelable(false);//使物理回退鍵失效
          builder.setTitle("shellway的博客");
          //設置點擊監聽事件
          builder.setMultiChoiceItems(items, flag, new DialogInterface.OnMultiChoiceClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                // TODO Auto-generated method stub
            
            }
          });
          //設置確定按鈕監聽事件
          builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                StringBuilder sb = new StringBuilder();
                
                for (int i = 0; i < items.length; i++) {
                    if(flag[i]){
                        sb.append(items[i]+" ");
                    }
                }
                String info =sb.toString();
                Toast.makeText(getApplicationContext(), info, 0).show();
            }
          });
          
          //創建dialog,並顯示
          Dialog dialog = builder.create();
          dialog.show();
    }
    
    //自定義對話框
    public void customDialog(View view){
          AlertDialog.Builder builder = new AlertDialog.Builder(this);
          builder.setCancelable(false);//使物理回退鍵失效
          builder.setTitle("shellway的博客");
          //加載自定義布局文件
          LayoutInflater mInflater = LayoutInflater.from(this);
          View dialogView = mInflater.inflate(R.layout.custom, null);
          builder.setView(dialogView);
          //創建dialog
          final Dialog dialog = builder.create();
          dialog.show();
          Button bt_ok = (Button) dialogView.findViewById(R.id.bt_ok);
          Button bt_cancel = (Button) dialogView.findViewById(R.id.bt_cancel);
          //設置按鈕監聽事件
          bt_ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();//讓對話框消失
            }
          } );
          //設置按鈕監聽事件
          bt_cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();//讓對話框消失
                }
         } );
    }
}
MainActivity.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
     >
 
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="generalDialog"
        android:text="普通對話框"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="selectedDialog"
        android:text="選擇對話框"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="singleChoiceDialog"
        android:text="單選對話框"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="multiChoiceDialog"
        android:text="多選對話框"
        />
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="customDialog"
        android:text="自定義對話框"
        />

</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <EditText 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入密碼"
        />
    <EditText 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="請再次輸入密碼"
        />
    
    <LinearLayout 
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:orientation="horizontal" >
       <Button 
            android:id="@+id/bt_ok"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="ok"
            android:text="確定"
           />
       <Button 
            android:id="@+id/bt_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="cancel"
            android:text="取消"
           />

   </LinearLayout>

</LinearLayout>
custom.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shellway.mydialog"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

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

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

</manifest>
AndroidManifest.xml

運行結果截圖:

 

 注意啦:本章復習筆記未完,后面會繼續更新完善。。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM