<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 4.5.2 Intent之復雜數據的傳遞 ## 本節引言: > 上一節中我們學習了Intent的一些基本使用,知道了Intent的七個屬性,顯式Intent以及 隱式Intent,以及如何自定義隱式Intent,最后還給大家提供了一些常用的系統Intent! 而本節跟大家講解的是Intent傳遞數據的問題~好的,開始本節內容~ ## 1.Intent傳遞簡單數據 > 還記得我們在Activity那里學過如何在兩個Activity中互相傳遞簡單數據的方法嗎? > > ![](http://www.runoob.com/wp-content/uploads/2015/08/71858311.jpg) > > 就是可以直接通過調用Intent的putExtra()方法存入數據,然后在獲得Intent后調用getXxxExtra獲得 對應類型的數據;傳遞多個的話,可以使用Bundle對象作為容器,通過調用Bundle的putXxx先將數據 存儲到Bundle中,然后調用Intent的putExtras()方法將Bundle存入Intent中,然后獲得Intent以后, 調用getExtras()獲得Bundle容器,然后調用其getXXX獲取對應的數據! 另外數據存儲有點類似于Map的&lt;鍵,值&gt;! ## 2.Intent傳遞數組 > 嘿嘿,普通類型倒沒問題,但是如果是數組咧?解決方法如下: **寫入數組**: ``` bd.putStringArray("StringArray", new String[]{"呵呵","哈哈"}); //可把StringArray換成其他數據類型,比如int,float等等... ``` **讀取數組**: ``` String[] str = bd.getStringArray("StringArray") ``` ## 3.Intent傳遞集合 > 嗯,數組很簡單吧,那我們再來傳下集合~這個就稍微復雜點了,分情況處理: ### 1)List&lt;基本數據類型或String&gt; **寫入集合:** ``` intent.putStringArrayListExtra(name, value) intent.putIntegerArrayListExtra(name, value) ``` **讀取集合:** ``` intent.getStringArrayListExtra(name) intent.getIntegerArrayListExtra(name) ``` ### 2)List&lt; Object&gt; 將list強轉成Serializable類型,然后傳入(可用Bundle做媒介) **寫入集合:** ``` putExtras(key, (Serializable)list) ``` **讀取集合:** ``` (List<Object>) getIntent().getSerializable(key) ``` **PS:Object類需要實現Serializable接口** ### 3)Map&lt;String, Object&gt;,或更復雜的 解決方法是:**外層套個List** ``` //傳遞復雜些的參數 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(); //須定義一個list用于在budnle中傳遞需要傳遞的ArrayList<Object>,這個是必須要的 ArrayList bundlelist = new ArrayList(); bundlelist.add(list); bundle.putParcelableArrayList("list",bundlelist); intent.putExtras(bundle); startActivity(intent); ``` ## 4.Intent傳遞對象 傳遞對象的方式有兩種:將對象轉換為Json字符串或者通過Serializable,Parcelable序列化 不建議使用Android內置的摳腳Json解析器,可使用fastjson或者Gson第三方庫! ### 1)將對象轉換為Json字符串 **Gson解析的例子:** **Model:** ``` public class Author{ private int id; private String name; //... } public class Author{ private int id; private String name; //... } ``` **寫入數據:** ``` 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); ``` **讀取數據:** ``` 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序列化對象 **1.Serializable實現:** > ①業務Bean實現:Serializable接口,寫上getter和setter方法 > ②Intent通過調用putExtra(String name, Serializable value)傳入對象實例 當然對象有多個的話多個的話,我們也可以先Bundle.putSerializable(x,x); > ③新Activity調用getSerializableExtra()方法獲得對象實例: eg:Product pd = (Product) getIntent().getSerializableExtra("Product"); > ④調用對象get方法獲得相應參數 **2.Parcelable實現:** **一般流程:** > ①業務Bean繼承Parcelable接口,重寫writeToParcel方法,將你的對象序列化為一個Parcel對象; > ②重寫describeContents方法,內容接口描述,默認返回0就可以 > ③實例化靜態內部對象CREATOR實現接口Parcelable.Creator > ④同樣式通過Intent的putExtra()方法傳入對象實例,當然多個對象的話,我們可以先 放到Bundle里Bundle.putParcelable(x,x),再Intent.putExtras()即可 **一些解釋:** > 通過writeToParcel將你的對象映射成Parcel對象,再通過createFromParcel將Parcel對象映射 成你的對象。也可以將Parcel看成是一個流,通過writeToParcel把對象寫到流里面, 在通過createFromParcel從流里讀取對象,只不過這個過程需要你來實現,因此寫的 順序和讀的順序必須一致。 **實現Parcelable接口的代碼示例:** ``` //Internal Description Interface,You do not need to manage @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int flags){ parcel.writeString(bookName); parcel.writeString(author); parcel.writeInt(publishTime); } public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() { @Override public Book[] newArray(int size) { return new Book[size]; } @Override public Book createFromParcel(Parcel source) { Book mBook = new Book(); mBook.bookName = source.readString(); mBook.author = source.readString(); mBook.publishTime = source.readInt(); return mBook; } }; ``` **Android Studio生成Parcleable插件:** Intellij/Andriod Studio插件android-parcelable-intellij-plugin 只要ALT+Insert,即可直接生成Parcleable接口代碼。 另外:Android中大量用到Parcelable對象,實現Parcable接口又是非常繁瑣的,可以用到 第三方的開源框架:Parceler,因為Maven的問題,暫時還沒試。 參考地址:[[Android的Parcelable自動生成]](http://www.race604.com/auto-parcelable-object/) **3.兩種序列化方式的比較:** 兩者的比較: * 1)在使用內存的時候,Parcelable比Serializable性能高,所以推薦使用Parcelable。 * 2)Serializable在序列化的時候會產生大量的臨時變量,從而引起頻繁的GC。 * 3)Parcelable不能使用在要將數據存儲在磁盤上的情況,因為Parcelable不能很好的保證數據的 持續性在外界有變化的情況下。盡管Serializable效率低點,但此時還是建議使用Serializable。 ## 5.Intent傳遞Bitmap bitmap默認實現Parcelable接口,直接傳遞即可 **實現代碼:** ``` Bitmap bitmap = null; Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putParcelable("bitmap", bitmap); intent.putExtra("bundle", bundle); ``` ## 6.傳來傳去不方便,直接定義全局數據 > 如果是傳遞簡單的數據,有這樣的需求,Activity1 -&gt; Activity2 -&gt; Activity3 -&gt; Activity4, 你想在Activity中傳遞某個數據到Activity4中,怎么破,一個個頁面傳么? > > 顯然不科學是吧,如果你想某個數據可以在任何地方都能獲取到,你就可以考慮使用 **Application全局對象**了! > > Android系統在每個程序運行的時候創建一個Application對象,而且只會創建一個,所以Application 是單例(singleton)模式的一個類,而且Application對象的生命周期是整個程序中最長的,他的生命 周期等于這個程序的生命周期。如果想存儲一些比靜態的值(固定不改變的,也可以變),如果你想使用 Application就需要自定義類實現Application類,并且告訴系統實例化的是我們自定義的Application 而非系統默認的,而這一步,就是在AndroidManifest.xml中衛我們的application標簽添加:**name屬性**! **關鍵部分代碼:** **1)自定義Application類:** ``` class MyApp extends Application { private String myState; public String getState(){ return myState; } public void setState(String s){ myState = s; } } ``` **2)AndroidManifest.xml中聲明:** ``` <application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name"> ``` **3)在需要的地方調用:** ``` class Blah extends Activity { @Override public void onCreate(Bundle b){ ... MyApp appState = ((MyApp)getApplicationContext()); String state = appState.getState(); ... } } ``` **高逼格寫法** :在任何位置都能獲取到Application全局對象。 Applicaiton是系統的一個組件,他也有自己的一個生命周期,我們可以在onCraete里獲得這個 Application對象。貼下修改后的代碼吧! ``` 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; } @Override public void onCreate(){ onCreate(); instance = this; } } ``` 然后在任意地方我們就可以直接調用:MyApp.getInstance()來獲得Application的全局對象! **注意事項:** > Application對象是存在于內存中的,也就有它可能會被系統殺死,比如這樣的場景: > > 我們在Activity1中往application中存儲了用戶賬號,然后在Activity2中獲取到用戶賬號,并且顯示! > > 如果我們點擊home鍵,然后過了N久候,系統為了回收內存kill掉了我們的app。這個時候,我們重新 打開這個app,這個時候很神奇的,回到了Activity2的頁面,但是如果這個時候你再去獲取Application 里的用戶賬號,程序就會報NullPointerException,然后crash掉~ > > 之所以會發生上述crash,是因為這個Application對象是全新創建的,可能你以為App是重新啟動的, 其實并不是,僅僅是創建一個新的Application,然后啟動上次用戶離開時的Activity,從而創造App 并沒有被殺死的假象!所以如果是比較重要的數據的話,建議你還是進行本地化,另外在使用數據的時候 要對變量的值進行非空檢查!還有一點就是:不止是Application變量會這樣,單例對象以及公共靜態變量 也會這樣~ ## 7.單例模式傳參 > 上面的Application就是基于單例的,單例模式的特點就是可以保證系統中一個類有且只有一個實例。 這樣很容易就能實現,在A中設置參數,在B中直接訪問了。這是幾種方法中效率最高的。 **范例代碼:(代碼來自于網上~)** ①定義一個**單例類**: ``` public class XclSingleton { //單例模式實例 private static XclSingleton instance = null; //synchronized 用于線程安全,防止多線程同時創建實例 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); } } ``` **②設置參數:** ``` XclSingleton.getInstance().put("key1", "value1"); XclSingleton.getInstance().put("key2", "value2"); ``` ## 本節小結: > 好的,關于Intent復雜數據傳輸就到這里,本節除了講述使用Intent來傳遞復雜數據外,還教了大家 使用Application和單例模式來傳遞參數!相信會對大家在數據傳遞方面帶來方便,謝謝~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看