如何在Activity间传递数据

来源:互联网 发布:egd网络黄金官网 编辑:程序博客网 时间:2024/05/21 22:12
1、基于消息的通信机制 Intent------bundle,extra

用这种方式一般而言,传递一些简单的类型是比较容易的,例如int,string等

详细介绍下Intent机制

Intent包含两部分:

1)目的【action】------要去到哪里去

2)内容【category、data】------路上带些什么,区分性数据和内容性数据

简单数据传递:

这里以ActivityA向ActivityB传递数据为例

Intent intent = new Intent(context, ActivityB.class);//如果context上下文不是Activity的话, 需要添加下面这个flagif (!(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传递数据步骤如下:

  1. 创建新class,取名MyApp,继承android.app.Application父类,并在MyApp中定义需要保存的属性,如:用户名,用户类型;
  2. 在Activity中,通过Activity.getApplication()方法获取到MyApp对象(需要强制转换),对其数据进行操作;
  3. 修改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;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();setName("Dick");}}

步骤二:

public class MainActivity extends Activity {private Button btn;private MyApp myApp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn=(Button)this.findViewById(R.id.btn);btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmyApp=(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-sdkandroid:minSdkVersion="8"android:targetSdkVersion="17" /><applicationandroid:name=".MyApp"android:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid: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之间的通信


0 0
原创粉丝点击