【转】Android 之最新最全的Intent传递数据方法
原文地址:https://www.jianshu.com/p/1169dba99261
intent傳遞數(shù)據(jù)
為什么要和intent單獨(dú)拿出來(lái)講,因?yàn)镮ntent傳遞數(shù)據(jù)也是非常重要的
一、簡(jiǎn)單的傳遞數(shù)據(jù)
二、傳遞數(shù)組
bd.putStringArray("StringArray", new String[]{"呵呵","哈哈"}); //可把StringArray換成其他數(shù)據(jù)類型,比如int,float等等..讀取數(shù)組:
String[] str = bd.getStringArray("StringArray")三、傳遞集合
1)List<基本數(shù)據(jù)類型或String>
intent.putStringArrayListExtra(name, value) intent.putIntegerArrayListExtra(name, value)讀取集合:
intent.getStringArrayListExtra(name) intent.getIntegerArrayListExtra(name)2)List< Object>
將list強(qiáng)轉(zhuǎn)成Serializable類型,然后傳入(可用Bundle做媒介)
寫(xiě)入集合:
putExtras(key, (Serializable)list)讀取集合:
(List<Object>) getIntent().getSerializable(key)PS:Object類需要實(shí)現(xiàn)Serializable接口
3)Map<String, Object>,或更復(fù)雜的
解決方法是:外層套個(gè)List
//傳遞復(fù)雜些的參數(shù) Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("key1", "value1"); map1.put("key2", "value2"); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); list.add(map1); Intent intent = new Intent(); intent.setClass(MainActivity.this,ComplexActivity.class); Bundle bundle = new Bundle(); //須定義一個(gè)list用于在budnle中傳遞需要傳遞的ArrayList<Object>,這個(gè)是必須要的 ArrayList bundlelist = new ArrayList(); bundlelist.add(list); bundle.putParcelableArrayList("list",bundlelist); intent.putExtras(bundle); startActivity(intent);四、Intent傳遞對(duì)象
傳遞對(duì)象的方式有兩種:將對(duì)象轉(zhuǎn)換為Json字符串或者通過(guò)Serializable,Parcelable序列化 不建議使用Android內(nèi)置的摳腳Json解析器,可使用fastjson或者Gson第三方庫(kù)!
1)將對(duì)象轉(zhuǎn)換為Json字符串
Gson解析的例子:
Model:
public class Book{ private int id; private String title; //... } public class Author{ private int id; private String name; //... }寫(xiě)入數(shù)據(jù):
Book book=new Book(); book.setTitle("Java編程思想"); Author author=new Author(); author.setId(1); author.setName("Bruce Eckel"); book.setAuthor(author); Intent intent=new Intent(this,SecondActivity.class); intent.putExtra("book",new Gson().toJson(book)); startActivity(intent);讀取數(shù)據(jù):
String bookJson=getIntent().getStringExtra("book"); Book book=new Gson().fromJson(bookJson,Book.class); Log.d(TAG,"book title->"+book.getTitle()); Log.d(TAG,"book author name->"+book.getAuthor().getName());2)使用Serializable,Parcelable序列化對(duì)象
但是不知道你有沒(méi)有發(fā)現(xiàn),putExtra()方法中所支持的數(shù)據(jù)類型是有限的,雖然常用的一些數(shù)據(jù)類型它都會(huì)支持,但是當(dāng)你想去傳遞一些自定義對(duì)象的時(shí)候就會(huì)發(fā)現(xiàn)無(wú)從下手。不用擔(dān)心,下面我們就學(xué)習(xí)一下使用Intent 來(lái)傳遞對(duì)象的技巧。
方式一:Serializable 方式
Serializable 是序列化的意思,表示將一個(gè)對(duì)象轉(zhuǎn)換成可存儲(chǔ)或可傳輸?shù)臓顟B(tài)。序列化后的對(duì)象可以在網(wǎng)絡(luò)上進(jìn)行傳輸,也可以存儲(chǔ)到本地。至于序列化的方法也很簡(jiǎn)單,只需要讓一個(gè)類去實(shí)現(xiàn)Serializable 這個(gè)接口就可以了。
比如說(shuō)有一個(gè)Person 類,其中包含了name 和age 這兩個(gè)字段,想要將它序列化就可以這樣寫(xiě):
其中g(shù)et、set 方法都是用于賦值和讀取字段數(shù)據(jù)的,最重要的部分是在第一行。這里讓Person 類去實(shí)現(xiàn)了Serializable 接口,這樣所有的Person 對(duì)象就都是可序列化的了。
接下來(lái)在FirstActivity 中的寫(xiě)法非常簡(jiǎn)單:
Person person = new Person(); person.setName("Tom"); person.setAge(20); Intent intent = new Intent(FirstActivity.this, SecondActivity.class); intent.putExtra("person_data", person); startActivity(intent);可以看到,這里我們創(chuàng)建了一個(gè)Person 的實(shí)例,然后就直接將它傳入到putExtra()方法中了。由于Person 類實(shí)現(xiàn)了Serializable 接口,所以才可以這樣寫(xiě)。
接下來(lái)在SecondActivity 中獲取這個(gè)對(duì)象也很簡(jiǎn)單,寫(xiě)法如下:
Person person = (Person) getIntent().getSerializableExtra("person_data");方式二:Parcelable
除了Serializable 之外,使用Parcelable 也可以實(shí)現(xiàn)相同的效果,不過(guò)不同于將對(duì)象進(jìn)行序列化,Parcelable 方式的實(shí)現(xiàn)原理是將一個(gè)完整的對(duì)象進(jìn)行分解,而分解后的每一部分都是Intent 所支持的數(shù)據(jù)類型,這樣也就實(shí)現(xiàn)傳遞對(duì)象的功能了。
下面我們來(lái)看一下Parcelable 的實(shí)現(xiàn)方式,修改Person 中的代碼,如下所示:
Parcelable 的實(shí)現(xiàn)方式要稍微復(fù)雜一些。可以看到,首先我們讓Person 類去實(shí)現(xiàn)了Parcelable 接口,這樣就必須重寫(xiě)describeContents()和writeToParcel()這兩個(gè)方法。其中describeContents()方法直接返回0 就可以了,而writeToParcel()方法中我們需要調(diào)用Parcel的writeXxx()方法將Person 類中的字段一一寫(xiě)出。注意字符串型數(shù)據(jù)就調(diào)用writeString()方法,整型數(shù)據(jù)就調(diào)用writeInt()方法,以此類推。
除此之外,我們還必須在Person 類中提供一個(gè)名為CREATOR 的常量,這里創(chuàng)建了Parcelable.Creator 接口的一個(gè)實(shí)現(xiàn),并將泛型指定為Person。接著需要重寫(xiě)createFromParcel()和newArray()這兩個(gè)方法,在createFromParcel()方法中我們要去讀取剛才寫(xiě)出的name 和age字段,并創(chuàng)建一個(gè)Person 對(duì)象進(jìn)行返回,其中name 和age 都是調(diào)用Parcel 的readXxx()方法讀取到的,注意這里讀取的順序一定要和剛才寫(xiě)出的順序完全相同。而newArray()方法中的實(shí)現(xiàn)就簡(jiǎn)單多了,只需要new 出一個(gè)Person 數(shù)組,并使用方法中傳入的size 作為數(shù)組大小就可以了。
接下來(lái)在FirstActivity 中我們?nèi)匀豢梢允褂孟嗤拇a來(lái)傳遞Person 對(duì)象,只不過(guò)在SecondActivity 中獲取對(duì)象的時(shí)候需要稍加改動(dòng),如下所示:
Person person = (Person) getIntent().getParcelableExtra("person_data");注意這里不再是調(diào)用getSerializableExtra()方法,而是調(diào)用getParcelableExtra()方法來(lái)獲取傳遞過(guò)來(lái)的對(duì)象了,其他的地方都完全相同。這樣我們就把使用Intent 來(lái)傳遞對(duì)象的兩種實(shí)現(xiàn)方式都學(xué)習(xí)完了,對(duì)比一下,Serializable的方式較為簡(jiǎn)單,在這里強(qiáng)調(diào)一下,網(wǎng)上很多博客很多文章都說(shuō)Parcelable要比Serializable效率要高,其實(shí)不然,在讀取速度方面Serializable其實(shí)他要比Parcelable更快,具體我們可以看一下這篇文章
http://www.jianshu.com/p/fcc59fb523b6
五、Intent傳遞Bitmap
bitmap默認(rèn)實(shí)現(xiàn)Parcelable接口,直接傳遞即可
Bitmap bitmap = null; Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putParcelable("bitmap", bitmap); intent.putExtra("bundle", bundle);六、定義全局?jǐn)?shù)據(jù),傳遞數(shù)據(jù)
如果是傳遞簡(jiǎn)單的數(shù)據(jù),有這樣的需求,Activity1 -> Activity2 -> Activity3 -> Activity4, 你想在Activity中傳遞某個(gè)數(shù)據(jù)到Activity4中,怎么破,一個(gè)個(gè)頁(yè)面?zhèn)髅?#xff1f;
顯然不科學(xué)是吧,如果你想某個(gè)數(shù)據(jù)可以在任何地方都能獲取到,你就可以考慮使用 Application全局對(duì)象了!
關(guān)鍵部分代碼:
第一步自定義Application類:
class MyApp extends Application { private String myState; public String getState(){ return myState; } public void setState(String s){ myState = s; } }第二步AndroidManifest.xml中聲明:
<application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name">第三步在需要的地方調(diào)用:
class Blah extends Activity {高逼格寫(xiě)法
:在任何位置都能獲取到Application全局對(duì)象。
Applicaiton是系統(tǒng)的一個(gè)組件,他也有自己的一個(gè)生命周期,我們可以在onCraete里獲得這個(gè) Application對(duì)象。貼下修改后的代碼吧!
class MyApp extends Application { private String myState; private static MyApp instance; public static MyApp getInstance(){ return instance; } public String getState(){ return myState; } public void setState(String s){ myState = s; }然后在任意地方我們就可以直接調(diào)用:MyApp.getInstance()來(lái)獲得Application的全局對(duì)象!
注意事項(xiàng):
Application對(duì)象是存在于內(nèi)存中的,也就有它可能會(huì)被系統(tǒng)殺死,比如這樣的場(chǎng)景:
我們?cè)贏ctivity1中往application中存儲(chǔ)了用戶賬號(hào),然后在Activity2中獲取到用戶賬號(hào),并且顯示!
如果我們點(diǎn)擊home鍵,然后過(guò)了N久候,系統(tǒng)為了回收內(nèi)存kill掉了我們的app。這個(gè)時(shí)候,我們重新 打開(kāi)這個(gè)app,這個(gè)時(shí)候很神奇的,回到了Activity2的頁(yè)面,但是如果這個(gè)時(shí)候你再去獲取Application 里的用戶賬號(hào),程序就會(huì)報(bào)NullPointerException,然后crash掉~(yú)
之所以會(huì)發(fā)生上述crash,是因?yàn)檫@個(gè)Application對(duì)象是全新創(chuàng)建的,可能你以為App是重新啟動(dòng)的, 其實(shí)并不是,僅僅是創(chuàng)建一個(gè)新的Application,然后啟動(dòng)上次用戶離開(kāi)時(shí)的Activity,從而創(chuàng)造App 并沒(méi)有被殺死的假象!所以如果是比較重要的數(shù)據(jù)的話,建議你還是進(jìn)行本地化,另外在使用數(shù)據(jù)的時(shí)候 要對(duì)變量的值進(jìn)行非空檢查!還有一點(diǎn)就是:不止是Application變量會(huì)這樣,單例對(duì)象以及公共靜態(tài)變量 也會(huì)這樣~
七、單例模式傳參
上面的Application就是基于單例的,單例模式的特點(diǎn)就是可以保證系統(tǒng)中一個(gè)類有且只有一個(gè)實(shí)例。 這樣很容易就能實(shí)現(xiàn),在A中設(shè)置參數(shù),在B中直接訪問(wèn)了。這是幾種方法中效率最高的。
范例代碼:(代碼來(lái)自于網(wǎng)上~)
①定義一個(gè)單例類:
public class XclSingleton { //單例模式實(shí)例 private static XclSingleton instance = null; //synchronized 用于線程安全,防止多線程同時(shí)創(chuàng)建實(shí)例 public synchronized static XclSingleton getInstance(){ if(instance == null){ instance = new XclSingleton(); } return instance; } final HashMap<String, Object> mMap; private XclSingleton() { mMap = new HashMap<String,Object>(); } public void put(String key,Object value){ mMap.put(key,value); } public Object get(String key) { return mMap.get(key); } }②設(shè)置參數(shù):
XclSingleton.getInstance().put("key1", "value1"); XclSingleton.getInstance().put("key2", "value2");
作者:侯蛋蛋_
鏈接:https://www.jianshu.com/p/1169dba99261
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
轉(zhuǎn)載于:https://www.cnblogs.com/kexing/p/8270667.html
總結(jié)
以上是生活随笔為你收集整理的【转】Android 之最新最全的Intent传递数据方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Hibernate Annotation
- 下一篇: 表空间管理