1. 程式人生 > >綜述種類:Android元件之間 資料傳遞方法

綜述種類:Android元件之間 資料傳遞方法

部落格時間2012-06-06 18:27

-------------------------------------------

思路

1通過共享appication做處理
2
先轉換成json,第二個activity再轉換回list
3 Parcelable Serializable 

public class SerializableMap implements Serializable {
      ArrayList<Map<String, Object>> listMap;
    //get set方法
}
最後通過putSerializable("listMap
", SerializableMap獲得listMap); 

-------------------------------------------

1  基於訊息的通訊機制 Intent--------boudle,extra

用這種簡單的形式,一般而言傳遞一些簡單的型別是比較容易的,如int、string等

詳細介紹下Intent機制

Intent包含兩部分:

1 目的【action】-------要去到哪裡去

2 內容【category、data】----------路上帶些什麼,區分性資料和內容性資料

簡單資料傳遞:

Intent intent = new Intent(LoginActivity.this, MainActivity.class);

intent.putExtra("flag", flag);

startActivity(intent);

////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////

String flag = "   ";

Intent intent1 = this.getIntent(); 

flag = intent1.getStringExtra("flag");

////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////

資料型別有限,遇到不可序列化的資料Bitmap,Inputstream,或者是LinkList連結串列等資料型別就不太好用了

2 利用static靜態資料,public static成員變數

我們千萬不要以為Davlik虛擬機器的垃圾回收器會幫助我們回收不需要的記憶體垃圾。事實上,回收器並不可靠,

尤其是手機上,是更加的不可靠。 因此,除非我們要使自己的程式變得越來越糟糕,否則儘量遠離static。

注:如果經常使用static的Bitmap、Drawable等變數。可能就會丟擲一個在Android系統中非常著名的異常(

以前budget這個單詞一直記不住什麼意思,自從經常丟擲這個異常後,這個單詞終於爛熟於心了,)

ERROR/AndroidRuntime(4958): Caused by: java.lang.OutOfMemoryError:bitmap size exceeds VM budget 注:如果經常使用static的Bitmap、Drawable等變數。可能就會丟擲一個在Android系統中非常著名的異常(

以前budget這個單詞一直記不住什麼意思,自從經常丟擲這個異常後,這個單詞終於爛熟於心了,)

3 基於外部儲存的傳輸 ,File/Preference/Sqlite,如果要針對第三方應用需要Content provider

作為一個完成的應用程式,資料儲存操作是必不可少的。因此,Android系統一共提供了四種資料儲存方式。

分別是:SharePreference、SQLite、Content Provider和File。由於Android系統中,資料基本都是私有的的

,都是存放於“data/data/程式包名”目錄下,所以要實現資料共享,正確方式是使用Content Provider。

  SQLite: SQLite是一個輕量級的資料庫,支援基本SQL語法,是常被採用的一種資料儲存方式。Android

為此資料庫提供了一個名為SQLiteDatabase的類,封裝了一些操作資料庫的API。

  SharedPreference: 除SQLite資料庫外,另一種常用的資料儲存方式,其本質就是一個xml檔案,常用於

儲存較簡單的引數設定。

  File: 即常說的檔案(I/O)儲存方法,常用語儲存大數量的資料,但是缺點是更新資料將是一件困難的

事情。

  ContentProvider: ContentProvider是安卓平臺中,在不同應用程式之間實現資料共享的一種機制。一個

應用程式如果需要讓別的程式可以操作自己的資料,即可採用這種機制。並且此種方式忽略了底層的資料儲存

實現,ContentProvider提供了一種統一的通過Uri實現資料操作的方式。

詳細介紹使用過程

File 通過檔案內容的讀取傳遞資料

Preference: SharedPreferences也是一種輕型的資料儲存方式,它的本質是基於XML檔案儲存key-value鍵值

對資料,通常用來儲存一些簡單的配置資訊

SharedPreferences物件本身只能獲取資料而不支援儲存和修改,儲存修改是通過Editor物件實現。實現

SharedPreferences儲存的步驟如下:

  一、根據Context獲取SharedPreferences物件

  二、利用edit()方法獲取Editor物件。

  三、通過Editor物件儲存key-value鍵值對資料。

  四、通過commit()方法提交資料。

   SharedPreferences sp=getSharedPreferences("login",0);//login儲存檔名    SharedPreferences.Editor se=sp.edit();;    se.putString("server", logEdit.getText().toString());    se.putString("port", portEdit.getText().toString());    se.commit();

////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////

  SharedPreferences ps=getSharedPreferences("login",0);//login是儲存檔案     server=ps.getString("server", "");   port=ps.getString("port", "");   logEdit.setText(server);   portEdit.setText(port);

////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////

ContentProvider

其步驟為:

  1. 在當前應用程式中定義一個ContentProvider。

  2. 在當前應用程式的AndroidManifest.xml中註冊此ContentProvider

  3. 其他應用程式通過ContentResolver和Uri來獲取此ContentProvider的資料。

 在程式A中,繼承ContProvider類,並重寫其中的方法

public class MyProvider extends ContentProvider{      @Override      public int delete(Uri uri, String selection, String[] selectionArgs) {          // TODO Auto-generated method stub          return 0;      }      @Override      public String getType(Uri uri) {          // TODO Auto-generated method stub          return null;      }      @Override      public Uri insert(Uri uri, ContentValues values) {          return null;      }      //在Create中初始化一個數據庫      @Override      public boolean onCreate() {          SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);          db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");          ContentValues values = new ContentValues();          values.put("name", "test");          db.insert("tab", "_id", values);          db.close();          return true;      }      //實現query方法      @Override      public Cursor query(Uri uri, String[] projection, String selection,              String[] selectionArgs, String sortOrder) {          SQLiteDatabase db = this.getContext().openOrCreateDatabase("test_db.db3", Context.MODE_PRIVATE, null);          Cursor c = db.query("tab", null, null, null, null, null,null);          return c;      }      @Override      public int update(Uri uri, ContentValues values, String selection,              String[] selectionArgs) {          // TODO Auto-generated method stub          return 0;      }  }

 在其AndroidManifest.xml中宣告此ContentProvider,其中authorities屬性定義了此ContentProvider的Uri

標識。

<provider android:name=".MyProvider" android:authorities="com.test.MyProvider"/>

在應用程式B中,通過ContentResolver獲取程式A的ContentProvider中的資料。

public class MainActivity extends Activity {      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);          //獲取上下文          Context ctx = MainActivity.this;          //獲取ContentResolver物件          ContentResolver resolver = ctx.getContentResolver();          //獲取Uri物件          Uri uri = Uri.parse("content://com.test.MyProvider");          //獲取資料          Cursor c = resolver.query(uri, null, null, null, null);          c.moveToFirst();          for(int i=0; i<c.getCount(); i++){              int index = c.getColumnIndexOrThrow("name");              String src = c.getString(index);              Log.d("", src);              c.moveToNext();          }      }  }

 再觀察兩個應用程式的結構,A的程式結構,可以清楚看到其有一個名為“test_db.db3”的資料庫,B的程

序結構,其並沒有任何資料庫用於儲存資料。由此圖,可以確定應用程式B中查詢出來的資料結果是來自於應

用程式A。

以上就是ContentProvider的使用方式,這種儲存方式相比SQLite和SharedPreferences,其複雜性是顯而易見

的,但是在處處可見“雲”的今天,程式間的資料互動需求令ContentProvider儲存機制變成必不可少的一部

分。

4 基於Ipc的通訊機制

context與service之間的傳輸,如Activity與Service之間的通訊

5 基於Application  Context

在一個activity初始化一個ArrayList<HashMap<Sting,Map>>物件,然後經過一個tableactivity,在傳遞到另

外一個activity,一開始直接考慮用putExtra,測試發現數據只能傳遞一次,就考慮用Application傳遞 Java裡面通常是用一個static的變數(例如singleton之類的)來同步activity之間(程式裡面類之間)的狀態。在android裡面比較靠譜的做法是用application context來關聯這些狀態。 每個activity都是context,裡面包含了執行時的狀態。同樣application也有一個context,android會保證這個context是唯一的例項。

package net.blogjava.mobile1;

import android.app.Application; import android.graphics.Bitmap; public class MyApp extends Application {     private Bitmap mBitmap;     public Bitmap getBitmap()     {         return mBitmap;     }     public void setBitmap(Bitmap bitmap)     {         this.mBitmap = bitmap;     } } <application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name"> </application> 獲得Bitmap物件的程式碼:     ImageView imageview = (ImageView)findViewById(R.id.ivImageView);     MyApp myApp = (MyApp)getApplication();     imageview.setImageBitmap(myApp.getBitmap());

上面兩段程式碼可以在任何的Service、Activity中使用。全域性的