【Android 开发】 : Activity之间传递数据的几种方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【Android 开发】 : Activity之间传递数据的几种方式相关的知识,希望对你有一定的参考价值。

参考技术A 1. 使用Intent来传递数据Intent表示意图,很多时候我们都会利用android的Intent来在各个Activity之间传递数据,这也是Android比较官方的一种数据传递的方式需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),其中利用Intent来传递数据程序Demo如下:IntentDemo.javapackage com.android.intentdemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class IntentDemo extends Activity private Button button; @Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); initComponent(); button.setOnClickListener(new View.OnClickListener() @Override public void onClick(View v) Intent intent = new Intent(IntentDemo.this, Other.class); // 在Intent中传递数据 intent.putExtra("name", "AHuier"); intent.putExtra("age", 22); intent.putExtra("address", "XiaMen"); // 启动Intent startActivity(intent); ); private void initComponent() button = (Button) findViewById(R.id.button); other.javapackage com.android.intentdemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; public class Other extends Activity private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); initComponent(); Intent intent = getIntent(); int age = intent.getIntExtra("age", 0); String name = intent.getStringExtra("name"); String address = intent.getStringExtra("address"); textView.setText("My age is " + age + "\n" + "My name is " + name + "\n" + "My address " + address); private void initComponent() textView = (TextView) findViewById(R.id.msg); ——>2. 在Activity之间使用静态变量传递数据在上例中使用Intent可以很方便的在不同的Activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性,就是Intent无法传递不能序列化的对象。我们可以使用静态变量来解决这个问题。需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),其中利用静态变量来传递数据程序Demo:IntentDemo.java Intent intent = new Intent(); intent.setClass(IntentDemo.this, Other.class); Other.age = 22; Other.name = "AHuier"; Other.address = "XiaMen"; startActivity(intent); Other.java private TextView textView; public static int age; public static String name; public static String address; @Override protected void onCreate(Bundle savedInstanceState) // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.other); initComponent(); textView.setText("My age is " + age + "\n" + "My name is " + name + "\n" + "My address " + address); ——>3. 通剪切板传递数据 在Activity之间数据传递还可以利用一些技巧,不管是Windows还是Linux操作系统,都会支持一种剪切板的技术,也就是一个程序将一些数据复制到剪切板上,然后其他的任何程序都可以从剪切板中获取数据。1) 利用剪切板传递普通的数据,如字符串需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),通过剪切板传递数据 程序Demo:IntentDemo.javaClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String name = "AHuier"; clipboardManager.setText(name); Intent intent = new Intent(IntentDemo.this, Other.class); startActivity(intent);Other.javaClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String msgString = clipboardManager.getText().toString(); textView.setText(msgString);——> 1) 利用剪切板传递复杂的数据,如对象需求1:从一个Activity(IntentDemo)跳转到另外一个Activity(Other),通过剪切板传递数据新建一个MyData.javapackage com.android.intentdemo; import java.io.Serializable; public class MyData implements Serializable private String name; private int age; public MyData(String name, int age) super(); this.name = name; this.age = age; // 提供一个toString()方法 @Override public String toString() return "MyData [name=" + name + ", age=" + age + "]"; public String getName() return name; public void setName(String name) this.name = name; public int getAge() return age; public void setAge(int age) this.age = age; IntentDemo.java MyData myData = new MyData("AHuier", 22); //将对象转换成字符串 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); String base64String = ""; try ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); objectOutputStream.writeObject(myData); //使用Android中提供的 Base64 工具类,这个类主要是用来对对象进行压缩也解码的过程,使用默认方式 base64String = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT); objectOutputStream.close(); catch (Exception e) // TODO: handle exception ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); clipboardManager.setText(base64String); Intent intent = new Intent(IntentDemo.this, Other.class); startActivity(intent); Other.java ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); String msgString = clipboardManager.getText().toString(); //将字符串 msgString 还原为对象 byte[] base64_byte = Base64.decode(msgString, Base64.DEFAULT); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64_byte); try ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); MyData myData = (MyData)objectInputStream.readObject(); textView.setText(myData.toString()); catch (Exception e) // TODO: handle exception ——>4.Intent中使用全局变量来传递数据需求1:从一个Activity(Main)跳转到另外一个Activity(Other),通过全局变量来传递数据Main.javaprivate Button button; private MyApp myApp; ... myApp = (MyApp)getApplication(); myApp.setName("kunhuixu"); //修改之后的名称 Intent intent = new Intent(Main.this, Other.class); startActivity(intent);Other.javaprivate MyApp myApp; private TextView textView; ... myApp = (MyApp)getApplication(); textView.setText("--- The app name ---" + myApp.getName());MyApp.javapackage com.android.intentglobal; import android.app.Application; /* * 查看Android官方文档。 * Application 是所有那些需要维护全局application状态的基类。你可以提供你自己的实现机制通过在在AndroidManifest.xml中提供你自己的需要声明 * 的标记你自己的标签。 * onCreate()方法是在应用程序启动的时候被回调的。 ——>本回答被提问者采纳

Android BroadcastReceiver、ContentProvider 和 Activity 之间的数据流?

【中文标题】Android BroadcastReceiver、ContentProvider 和 Activity 之间的数据流?【英文标题】:Dataflow between Android BroadcastReceiver, ContentProvider, and Activity? 【发布时间】:2010-10-14 07:46:02 【问题描述】:

我开发了一个接收广播的应用程序,然后 启动Activity,其中Activity 查询ContentProvider 实时从 DNS 中提取信息。

我希望能够洗牌,而不是去:

BroadcastReceiver.onReceive() 
  Intent intent = new Intent(...);
  intent.setData(...); // set a single String data
  context.startActivity(intent);


Activity.onCreate() 
  String value = intent.getData();  // get the String data
  Cursor = ContentProvider.query(search);
  ...
  setContentView(...);

它去了:

BroadcastReceiver.onReceive() 
  Cursor = ContentProvider.query(...);
  if (cursor != null) 
     Intent intent = new Intent(...);
     // how do I pass the cursor?
     getContext().startActivity(intent);
  


Activity.onCreate() 
  // how do I retrieve the cursor?
  setContentView(...);

即如果query() 没有返回数据,我想错过启动 Activity,并允许广播消息正常通过。

如果 query() 确实返回数据,我希望将 Cursor 提供给 Activity,这样我就不用再去查询数据了。

反过来,Activity 有自己的用户界面,用户需要对其做出响应。

这可能吗?

【问题讨论】:

【参考方案1】:

你想要的有点困难,对我来说,效率很低。我建议您使用第一种替代方案,但是当您在活动中加载光标时,检查是否没有数据,然后退出活动。

BroadcastReceiver.onReceive() 
  Intent intent = new Intent(...);
  intent.setData(...); // set a single String data
  context.startActivity(intent);


Activity.onCreate() 
  String value = intent.getData();  // get the String data
  Cursor = ContentProvider.query(search);

  if(cursor.isEmpty() ...)
    finish();
    return;
  
  ...
  setContentView(...);

这将具有完全相同的效果,光标只会加载一次,并且只有在光标中存在某些内容时才会显示活动。唯一的额外开销是无论如何都会触发意图,但这并不完全是征税:)

请注意,不会有任何闪烁或任何东西,Android 会处理在 onCreate() 中调用完成的情况(我相信 onStart 和 onResume 也是如此),因此用户永远不会知道它发生了。

【讨论】:

好的,听起来不错 - 但是 - 对 context.startActivity() 的调用何时返回? 我如何让 BroadcastReceiver 知道 Activity 是否做了任何有用的事情? AFAIK 我不能在 BroadcastReceiver 中使用 startActivityForResult()。 对 context.startActivity 的调用立即返回,本质上,它所做的只是安排活动在主事件线程空闲后立即启动。 嗯,这取决于您希望广播接收器做什么。在不知情的情况下,我建议您执行您计划让广播接收器在 Activity 中执行的任何操作。 我正在捕捉 NEW_OUTGOING_CALL 动作,但如果我启动 Activity,我必须将 BroadcastReceiver 的 returnData 设置为 null,否则调用会正常进行。如果我最终将出站调用放在 Activity 中,那么用户就不可能链接 BroadcastRecevers。【参考方案2】:

您需要找到或制作一个可序列化或可打包的游标(然后使用 intent.setExtra())。或者也许可以改为将所有数据作为一个包裹读取并将其传递给 Activity?

【讨论】:

这也是我的想法——可能是 Parcelable,因为 Activity 实际上是 ListActivity,所以我需要通过 ListAdapter 传递数据。

以上是关于【Android 开发】 : Activity之间传递数据的几种方式的主要内容,如果未能解决你的问题,请参考以下文章

Android开发 Activity之间传递图片(Bitmap)的方法

ANDROID开发之问题积累及解决方案(不断更新)

Android中Activity之间的数据传递ngti

android 两个activity之间切换会有飞入的效果,请问怎么去掉这个效果

Android BroadcastReceiver、ContentProvider 和 Activity 之间的数据流?

Android Studio中如何在Activity跳转之间传递数据