組件我們有了,那么我們缺少一個組件之間傳遞信息的渠道。利用Intent做載體,這是一個王道的做法。還有呢,可以利用文件系統來做數據共享。也可以使用Application設置全局數據,利用組件來進行控制數據。
一、Intent數據傳遞
- 那么首先是簡單的跳轉。我們可以借助bundle這個容器來存放我們想要傳遞的數據。
Intent intent = new Intent(); intent.setClass(activity1.this, activity2.class); //描述起點和目標 Bundle bundle = new Bundle(); //創建Bundle對象 bundle.putString("tag", "Activity1發來的數據"); //裝入數據 intent.putExtras(bundle); //把Bundle塞入Intent里面 startActivity(intent); //開始切換
另一個接受數據
Intent intent = this.getIntent(); //獲取已有的intent對象 Bundle bundle = intent.getExtras(); //獲取intent里面的bundle對象 string = bundle.getString("tag"); //獲取Bundle里面的字符串
- 那么接下來是如何接受從目標Activity返回的處理結果。這里有兩種方式,一是在onRestart方法里面接受處理結果,方法實現和Activity2接受從Activity1發來的數據處理一樣。另一種方式,是采用應答模式切換。這里,主要下第二種方式。應答模式切換和普通的切換不同在於,普通的是有去沒回,應答則是有來有往。代碼實現也不一樣:
從Activity1 切換到Activity2:startActivityForResult(intent,0);從Activity2返回到 Activity1:setResult(RESULT_OK, intent)。接受返回結果:protected void onActivityResult()。具體代碼如下:
發送方:
Intent intent = new Intent(); intent = intent.setClass(Activity1.this, AnotherActivity.class); Bundle bundle = new Bundle(); bundle.putString("string","cpacm"); intent.putExtras(bundle); startActivityForResult(intent,0); //只有這里不同,這里的0是請求碼,用於返回數據的識別 //Activity1.this.finish(); //不能用finish,會觸發onDestroy();
接收方:
Intent intent = new Intent(); intent = intent.setClass(AnotherActivity.this, Activity1.class); Bundle bundle = new Bundle(); bundle.putInt("result", "Activity2的處理結果"); intent.putExtras(bundle); AnotherActivity.this.setResult(RESULT_OK, intent); //RESULT_OK是返回狀態碼 AnotherActivity.this.finish(); //會觸發onDestroy();
發送方接受消息:(其中requestCode是請求碼,可以根據請求碼的不同來區分不同的處理模塊)
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch(resultCode) { //根據狀態碼,處理返回結果 case RESULT_OK: Bundle bundle =data.getExtras(); //獲取intent里面的bundle對象 String result = bundle.getInt("result"); break; default: break; } }
二、文件系統做數據共享
- 通過 Context.getSharedPreferences(String fileName,int mode)方法,可以打開一個xml文件,文件的位置在/data/data/package_name/shared_prefs /fileName.xml,如果不存在,則會自動創建。可以對該文件進行讀寫操作,在應用內的各組件之間共享數據。如果將mode設置為 Context.MODE_WORLD_READ或者Context.MODE_WORLD_WRITE,則還可以被其他應用訪問到。不過這不是 android推薦的方式,要實現跨應用共享數據,推薦的方式是用ContentProvider實現 。具體實現方法可以看以前寫的文章Android數據存儲(上)和Android數據存儲(下)。
- 除了比較方便的shared_prefs,也可以創建自定義文件,方法是Context.openFileOutput(),可以在/data/data /package_name/files/目錄下創建指定的文件,除此以外,和上面提到的shared_prefs都一樣。不過操作起來就復雜一些了。要 讀取用這種方式創建的文件,可以用Context.openFileInput()方法。
- 此外,還可以在SD卡上操作文件,通過標准的java.io包內的API就可以。不過要注意的是,SD卡內采用的是FAT文件系統,所以不支持linux 的文件讀寫權限控制,這點和shared_prefs與file不太一樣。如果需要對文件進行讀寫權限控制,就不能采用寫入SD卡的方式。
- 也可以用android自帶的SQLite數據庫來做數據持久化,主要用到的類包括SQLiteOpenHelper和SQLiteDatabase。
三、Application設置全局數據
在java中,我們使用全局變量時一般都會使用靜態變量,然后public類型,讓所有類都可以使用這些變量。當然在Android也可以這樣做。不過在這里說的是我們可以使用Application來管理這些變量。Application類是一個基類,這個基類的作用是為了獲取整個應用程序的狀態。 我們可以自己繼承或實現這個類,當你要使用自己拓展的application類的時候,只要在manifest.xml中 的<application>標簽中name應用自己定義的類就行了,這樣做的結果是:當你的應用程序或者包所在的進程創建的時候,這個類就 會被實例化。
使用的方法很簡單,首先繼承Application類再去把它重寫,主要重寫里面的onCreate方法,就是創建的時候,初始化變量的值。然后在整個應用中的各個文件中就可以對該變量進行操作了。
啟動Application時,系統會創建一個PID,即進程ID,所有的Activity就會在此進程上運行。那么我們在Application創建的時候初始化全局變量,同一個應用的所有Activity都可以取到這些全局變量的值,換句話說,我們在某一個Activity中改變了這些全局變量的值, 那么在同一個應用的其他Activity中值就會改變。這樣我們就達到了控制全局變量的目的。(當然application不僅僅局限於這里,它可以配合開發者設置更多的功能)
下面一個小例子:
public class MyApp extends Application{ private String learn; public String getLearn(){ return learn; } public void setLearn(String s){ this.learn= s; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); setLearn("cpacm"); //初始化全局變量 } }
上面就是一個繼承了Application類的簡單使用,我們只是新建了一個字符串變量。沒有全局,也沒有靜態,要使用它必須要通過MyApp才行。
接下來看看我們怎么使用它:
public class mainActivity extends Activity { private MyYApp myApp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myApp= (MyYApp) getApplication(); //獲得自定義的應用程序YApp Log.d("TEST", "InitLabel:"+myApp.getLearn()); //將我們放到進程中的全局變量拿出來,看是不是我們曾經設置的值 myApp.setLearn("ahaha"); //修改一下 Log.d("TEST", "ChangeLabel:"+myApp.getLearn()); //看下,這個值改變了沒有 } }
最后在配置文件中注冊自己定義的App
<!-- 在這里,將默認的Application設置成自己做的MyApp--> <application android:name="MyApp" .../>
四、組件控制數據
- 第一個當然是正統的ContentProvider組件了,怎么使用它,請看這篇博文,這里就不再講述了。Android四大組件之ContentProvider。
- service也可以充當數據控制的組件,畢竟service是在后台運行,當它與Activity綁定時,activity就可以從里面獲取數據(前提是service沒有被銷毀)。詳情:Android四大組件之Service
- 廣播組件也可以,更可以使用sendOrderedBroadcast(intent, null, BroadcastReceiver(), null, Activity.RESULT_OK, null, null);方法對返回的數據進行處理.這個方法是在原有的廣播序列的末尾再加一個廣播,並作為最后的一個廣播,可以對返回的信息進行處理。詳情:Android四大組件之Broadcast Receiver
五、結束語
呼~從寫第一篇博文開始,到現在已經一個月了,不知不覺中時間就過去了呢。期間斷斷續續地寫了十幾篇博文,不過寫的好也罷,寫的不好也罷,反正博主感覺自己收獲很大,和以前的想要什么功能就去學什么那樣片段式的學習相比,現在這種全面學習感覺好多了。
到這里為止,Android入門篇的組件部分就基本上完畢了,當然里面還有很多內容可以深究,這方面要大家自己挖掘了。那么接下來就是Android的控件部分了,額,一想到那么多的控件頭都大了,不過基本原理都是相通的,舉一反三嘛~好了,如果有什么問題也可以聯系我一起探討學習,最后希望大家Have a good day.
========================================
作者:cpacm
出處:(http://www.cpacm.net/2015/03/26/Android開發日記(九)——Android組件間的數據傳輸/)