如何在Activity間傳遞資料
阿新 • • 發佈:2019-02-14
1、基於訊息的通訊機制 Intent------bundle,extra
用這種方式一般而言,傳遞一些簡單的型別是比較容易的,例如int,string等
詳細介紹下Intent機制
Intent包含兩部分:
1)目的【action】------要去到哪裡去
2)內容【category、data】------路上帶些什麼,區分性資料和內容性資料
簡單資料傳遞:
使用方法
3、使用全域性變數在Activity之間傳遞資料
在整個Android程式中,有時需要儲存某些全域性的資料(如:使用者資訊),方便在程式的任何地方呼叫。在Activity之間資料傳遞中有一種比較使用的方式,就是全域性物件,使用過J2EE的都應該知道JavaWeb的四個作用域,其中Application域在應用程式的任何地方都可以使用和訪問,除非是Web伺服器停止,Android中的全域性物件非常類似於JavaWeb中的Application域,除非是Android應用程式清除記憶體,否則全域性物件將一直可以訪問。
在啟動Application時,系統會建立一個PID,即程序ID,所有的Activity就會在此主程序上執行。所以,在同一Application中所有的Activity都可以通過Activity.getApplication()方法獲取到同一個Application物件,繼承Application類,即可訪問自定義資料。
使用Application傳遞資料步驟如下:
步驟二:
步驟三:
4、使用剪下板在Activity之間傳遞物件資料
Activity1:
Activity2:
5、基於外部儲存的傳輸(File/Preference/SQLite,如果要針對第三方應用需要Content provider)
SQLite: SQLite是一個輕量級的資料庫,支援基本SQL語法,是常被採用的一種資料儲存方式。Android為此資料庫提供了一個名為SQLiteDatabase的類,封裝了一些操作資料庫的API。
SharedPreference: 除SQLite資料庫外,另一種常用的資料儲存方式,其本質就是一個xml檔案,常用於儲存較簡單的引數設定。
File: 即常說的檔案(I/O)儲存方法,常用語儲存大數量的資料,但是缺點是更新資料將是一件困難的事情。
ContentProvider: ContentProvider是安卓平臺中,在不同應用程式之間實現資料共享的一種機制。一個應用程式如果需要讓別的程式可以操作自己的資料,即可採用這種機制。並且此種方式忽略了底層的資料儲存實現,ContentProvider提供了一種統一的通過Uri實現資料操作的方式。在處處見“雲”的今天,程式間的資料互動需求令ContentProvider儲存機制變成必不可少的一部分。
6、基於Ipc的通訊機制
context與service之間的傳輸,如Activity與Service之間的通訊
用這種方式一般而言,傳遞一些簡單的型別是比較容易的,例如int,string等
詳細介紹下Intent機制
Intent包含兩部分:
1)目的【action】------要去到哪裡去
2)內容【category、data】------路上帶些什麼,區分性資料和內容性資料
簡單資料傳遞:
這裡以ActivityA向ActivityB傳遞資料為例
Intent intent = new Intent(context, ActivityB.class); //如果context上下文不是Activity的話, 需要新增下面這個flag if (!(context instanceof Activity)) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } //新增要傳遞的資料 intent.putExtra(key, value); //或則將資料打包進Bundle裡 Bundle bundle = new Bundle(); bundle.putString(key, value); intent.putExtras(bundle); context.startActivity(intent);
在ActivityB中
public void onCreate(Bundle savedInstanceState) {
//得到傳遞過來的資料
Intent intent=new Intent();
Bundle bundle =intent.getExtras();
//通過getXXX方法來獲取key對應的value
bundle.getXXX(key); //intent.getXXX(key);
}
資料型別有限,遇到不可序列化的資料Bitmap和Inputstream等,或者是LinkList等連結串列資料型別就不太好用了
2、使用static靜態變數傳遞資料(謹慎使用)
我們千萬不要以為Davlik虛擬機器的垃圾回收器會幫助我們回收不需要的記憶體垃圾。事實上,回收器並不可靠, 尤其是手機上,是更加的不可靠。 因此,除非我們要使自己的程式變得越來越糟糕,否則儘量遠離static。
如果經常使用static的Bitmap、Drawable等變數,可能就會丟擲一個在Android系統中非常著名的異常:
ERROR/AndroidRuntime(4958): Caused by: Java.lang.OutOfMemoryError: bitmap size exceeds VM budget
使用方法
在目標activity中宣告靜態變數,但必須是public修飾的
public class OtherActivity extends Activity {
//定義靜態變數
public static String name;
public static int age;
private TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
textview = (TextView)findViewById(R.id.msg);
textview.setText("name: "+name+"\n"+"age: "+age);
}
}
在其他activity中可以直接使用靜態變數傳遞資料給目標activity
public class MainActivity extends Activity {
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)this.findViewById(R.id.st);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MainActivity.this, OtherActivity.class);
OtherActivity.name="mayi";//直接呼叫靜態變數
OtherActivity.age=23;
startActivity(intent);
}
});
}
}
3、使用全域性變數在Activity之間傳遞資料
在整個Android程式中,有時需要儲存某些全域性的資料(如:使用者資訊),方便在程式的任何地方呼叫。在Activity之間資料傳遞中有一種比較使用的方式,就是全域性物件,使用過J2EE的都應該知道JavaWeb的四個作用域,其中Application域在應用程式的任何地方都可以使用和訪問,除非是Web伺服器停止,Android中的全域性物件非常類似於JavaWeb中的Application域,除非是Android應用程式清除記憶體,否則全域性物件將一直可以訪問。
在啟動Application時,系統會建立一個PID,即程序ID,所有的Activity就會在此主程序上執行。所以,在同一Application中所有的Activity都可以通過Activity.getApplication()方法獲取到同一個Application物件,繼承Application類,即可訪問自定義資料。
使用Application傳遞資料步驟如下:
- 建立新class,取名MyApp,繼承android.app.Application父類,並在MyApp中定義需要儲存的屬性,如:使用者名稱,使用者型別;
- 在Activity中,通過Activity.getApplication()方法獲取到MyApp物件(需要強制轉換),對其資料進行操作;
- 修改AndroidManifest.xml檔案中的application節點的android:name屬性(android:name=".MyApp")。
public class MyApp extends Application {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
setName("Dick");
}
}
步驟二:
public class MainActivity extends Activity {
private Button btn;
private MyApp myApp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=(Button)this.findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myApp=(MyApp)getApplication();
myApp.setName("jack");
Intent intent=new Intent(MainActivity.this, OtherActivity.class);
startActivity(intent);
}
});
}
}
步驟三:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.bgxt.staticchuandi"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="cn.bgxt.staticchuandi.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".OtherActivity"/>
</application>
</manifest>
4、使用剪下板在Activity之間傳遞物件資料
Activity1:
Person person = new Person("wulianghuan","22");
//將物件轉換成字串
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String base64String = "";
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(person);
base64String = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
//從Android系統中呼叫剪下板的服務
ClipboardManager clipboardManager = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
//在剪下板中放入要傳遞的資料
clipboardManager.setText(base64String);
//定義一個意圖
Intent intent = new Intent(Activity1.this,Activity2.class);
startActivity(intent);
Activity2:
text_name = (TextView) findViewById(R.id.name);
//從Android系統中呼叫剪下板的服務
ClipboardManager clipboardManager = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
String getString = clipboardManager.getText().toString();
//字串還原成物件
byte[] base64_byte = Base64.decode(getString, Base64.DEFAULT);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64_byte);
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
Person person = (Person)objectInputStream.readObject();
Log.i("OtherActivity", person.toString());
//設定文字框的資料
text_name.setText(person.toString());
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
5、基於外部儲存的傳輸(File/Preference/SQLite,如果要針對第三方應用需要Content provider)
SQLite: SQLite是一個輕量級的資料庫,支援基本SQL語法,是常被採用的一種資料儲存方式。Android為此資料庫提供了一個名為SQLiteDatabase的類,封裝了一些操作資料庫的API。
SharedPreference: 除SQLite資料庫外,另一種常用的資料儲存方式,其本質就是一個xml檔案,常用於儲存較簡單的引數設定。
File: 即常說的檔案(I/O)儲存方法,常用語儲存大數量的資料,但是缺點是更新資料將是一件困難的事情。
ContentProvider: ContentProvider是安卓平臺中,在不同應用程式之間實現資料共享的一種機制。一個應用程式如果需要讓別的程式可以操作自己的資料,即可採用這種機制。並且此種方式忽略了底層的資料儲存實現,ContentProvider提供了一種統一的通過Uri實現資料操作的方式。在處處見“雲”的今天,程式間的資料互動需求令ContentProvider儲存機制變成必不可少的一部分。
6、基於Ipc的通訊機制
context與service之間的傳輸,如Activity與Service之間的通訊