Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 論Android中的值傳遞

論Android中的值傳遞

編輯:關於Android編程

 

眾所周知,根據mvc設計模式,數據是要通過model來傳遞的,從一個activity(以下簡稱A)到另外一個activity(以下簡稱B)如果要傳值的話我們可以將model放到intent中(也可以不放),然後在B創建之後取得相應的值;反之,如果從B回傳值給A的話,也是可行的,只不過要在A的onActivityResult中接收相應的值。這幾種方法各有優缺點,大家自己可以結合實際情況來選擇。
本文的中心思想交代完畢,下面就開始看具體的代碼演示吧。
一、通過model傳值

直接通過model傳值

這種方法非常簡單,我們可以通過新建一個數據源單例DataSource,然後將所有的model都放在裡面,需要傳值的時候直接給model賦值即可。
以下展示數據源DataSource核心代碼:

public class DataSource {
    public Job job;

    private static DataSource instanceDataSource;
    public static DataSource shareInstance(){
        if (null == instanceDataSource) {
            instanceDataSource = new DataSource();
        }
        return instanceDataSource;
    }
}

好,假設我們現在有一個工作列表頁(JobActivity,圖一)和工作詳情頁(JobDetailActivity,圖二),最常見的情形莫過於選擇列表頁的某個item,進入詳情頁。那麼傳值的話核心代碼如下:
圖一
圖二

//位於JobActivity中,點擊列表頁的某項,相應了listview的onItemClick方法
public void onItemClick(AdapterView parent, View view, int position, long id) {
        Intent intent = new Intent();
        //mJobs這個成員變量是Listview的數據來源,給數據源的某個model(即job)賦值,由於datasource 是單例,所有的成員變量一旦賦值,就會常駐內存,不會變化,因此傳遞的值是不會變化的
        DataSource.shareInstance().job = JobActivity.this.mJobs.get(position);
        intent.setClass(this, JobDetailActivity.class);
        this.startActivity(intent);
    }

以下是接受值的核心代碼

//位於JobDetailActivity中,在oncreate方法中
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_job_detail);
        //取得相應的model
        Job job = DataSource.shareInstance().job;
        //雖然多此一舉,但還是做個判斷吧,哈哈!
        if (null != job) {
            titleTextView = (TextView) findViewById(R.id.jobdetail_title_textview);
            titleTextView.setText(null != job.jobName ? job.jobName : );
            areaTextView = (TextView) findViewById(R.id.jobdetail_area_textview);
            areaTextView.setText(null != job.workArea ? job.workArea : );
            salaryTextViearw = (TextView) findViewById(R.id.jobdetail_salary_textview);
            salaryTextViearw.setText(null != job.workSalary ? job.workSalary : );
            companyTextView = (TextView) findViewById(R.id.jobdetail_company_textview);
            companyTextView.setText(null != job.workCompany ? job.workCompany : );
            contactTextView = (TextView) findViewById(R.id.jobdetail_contact_textview);
            contactTextView.setText(null != job.workContact ? job.workContact : );
        }
}

這種傳值方式最大的優勢就是通俗易懂,簡單粗暴。而且確實是使用了mvc設計模式的,最主要的是可以實現雙向傳值,也就是從A到B可以傳遞,從B到A也可以,相當方便,是進階優秀程序員的必備方法,缺點也是有的:
(1),對象常駐內存,如果遇到大的model的話會比較吃內存(當然,也可以通過及時設置model為null來解決這個問題。)
(2)因為DataSource是單例,多線程肯定是要考慮的問題了。本文為了演示方便,沒有考慮並發的情況。但開發中就必須要考慮了,試想一種情況,主線程在獲取job對象後,後台我們啟動的某個線程在更改job對象的值,然後呢。。。。。數據肯定是會出問題了!總而言之,這是考驗閣下技術的最好的傳值方法。

將model設置到Intent中傳值

Android 的設計人員命名總是讓人有些摸不透,比如頁面不像ios一樣叫controller,也不叫page,而是叫Activity。兩個Activity傳值的類取名intent,也就是“意圖”的意思,實在不知道他們的“意圖”是什麼。
廢話少說,直接上核心代碼:
intent傳遞model的核心方法是:

Intent  putExtra(String name, Bundle value)

這個bundle就是我們將要傳遞的對象了
首先,我們要序列化我們的Job對象:

//job類後面的 implements Serializable兩個關鍵字就是序列化!
public class Job implements Serializable{

    public String jobName;
    public String jobId;
    public String workArea;
    public String workTime;
    public String workSalary;
    public String workDescription;
    public String workCompany;
    public String workContact;
    public String poster;

}

下面開始傳值啦!

Intent intent = new Intent(this,JobDetailActivity.class);  
        Bundle bundle = new Bundle();
        //job對象是之前序列化了的對象  
        bundle.putParcelable(PAR_KEY, job);  
        intent.putExtras(bundle);  

第二種方法演示完畢,不知大家看了以後有沒有什麼感受,是不是感覺沒有第一種爽?但還可以啦,湊合湊合看看吧,繼續往下就更麻煩了,繼續遵循我們的由易到難原則往下看吧!

二、通過intent回傳值

1.回傳值不管在ios或者Android上都是相對來說比較麻煩的,ios中初期通過代理傳遞,後期如果技術可以了,您可以直接把傳值跟傳遞控制權分開來玩耍,很帶感!
Android中回傳值涉及到兩個方法

startActivityForResult() 
onActivityResult()

設想一個場景,JobActivity中要實現根據地區篩選工作,那麼你就得有一個地區選擇頁面(AreaSelectActivity,見圖三),選擇地區回來後重新刷新Listview來加載相應地區的工作。
圖三
所以,我們要在用戶在AreaSelectActivity上選擇地區後把AreaSelectActivity這個頁面finish掉,然後告訴JobActivity用戶選擇了某個地區,需要把所有這個地區的工作過濾出來。
好了,背景交代完畢,接下來開始動手吧。
1.在JobActivity的filter按鈕點擊後編寫如下代碼:

public void onClick(View v) {
        switch (v.getId()) {
        //id為job_area_button的button是如圖一所示的filter按鈕
        case R.id.job_area_button: {
            Intent intent = new Intent();
            //設置要跳轉的activity
            intent.setClass(this, AreaSelectActivity.class);
            //這句話很關鍵,就是之前我交代的兩個方法中的第一個,區別於startActivity方法的是,他告訴編譯器,我這個頁面是要接受下一個頁面的回傳值的。RESULT_CODE_AREASELECT是我自己寫的常量,大家可以用任何整型變量代替
            startActivityForResult(intent, RESULT_CODE_AREASELECT);
        }

            break;
        }
}

2.在AreaSelectActivity這個activity中點擊某個item後編寫如下代碼:

public void onItemClick(AdapterView parent, View view, int position, long id) {
        switch (parent.getId()) {
        //這個id位area_all_listview的是AreaSelectActivity的listview
        case R.id.area_all_listview: {
            Intent intent = new Intent(this,JobActivity.class);
            intent.putExtra(position, position);
            //關鍵是這句話,他告訴前一個activity(也就是JobActivity)我這邊設置了一個tag,RESULT_OK,用來區分是哪一個activity傳遞過來的值(因為可以JobActivity可能要接受多個activity的回傳值)
            setResult(RESULT_OK, intent);
            this.finish();
        }
            break;
        }
}

3.在JobActivity中接受回傳值:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (JobActivity.RESULT_CODE_AREASELECT == requestCode) {
            if (null == data) {
                return;
            }
            int position = data.getIntExtra(position, 0);
            System.out.println(postion: + position);
        }
}

先解釋一下onActivityResult中的幾個參數的意思吧,
(1)requestCode:不言而喻,就是請求碼,也就是我之前設置的常量RESULT_CODE_AREASELECT
(2)resultCode:不多說,就是返回碼,也就是RESULT_OK了
(3)data:傳過來的數據,使用intent封裝好的。
所以呢,我們就先判斷這個請求碼是不是
JobActivity.RESULT_CODE_AREASELECT
如果是的話,就說明是AreaSelectActivity回傳回來的,那我們的邏輯就在裡面寫了。取到裡面的intent中的position即可。

好了,所有的傳值方法都介紹完畢了,好累啊,歡迎大家多多交流!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved