Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何通过bundle发送对象_Android_Serialization_Android Activity_Bundle_Parcelable - Fatal编程技术网

Android 如何通过bundle发送对象

Android 如何通过bundle发送对象,android,serialization,android-activity,bundle,parcelable,Android,Serialization,Android Activity,Bundle,Parcelable,我需要通过一个bundle传递一个对类的引用,该类完成了我的大部分处理 问题是它与意图或上下文无关,并且有大量的非原始对象。如何将类打包成可打包/序列化的类,并将其传递给startActivityForResult?您可以使用全局状态 更新: 自定义并将其添加到您的AndroidManifest.xml中: <application android:label="@string/app_name" android:debuggable="true" android:name=".Custo

我需要通过一个bundle传递一个对类的引用,该类完成了我的大部分处理

问题是它与意图或上下文无关,并且有大量的非原始对象。如何将类打包成可打包/序列化的类,并将其传递给
startActivityForResult

您可以使用全局状态

更新:

自定义并将其添加到您的AndroidManifest.xml中:

<application android:label="@string/app_name" android:debuggable="true" android:name=".CustomApplication"
由于“”的原因,您可以这样使用它:

CustomApplication application = (CustomApplication)getApplication();
application.someVariable = 123; 

希望这会有所帮助。

可包裹的界面是传递对象的好方法

这是一个关于如何使用Parcelable的非常好的答案


该官员还提供了一个示例

您还可以制作您的对象并使用捆绑包的功能和方法。

要想知道要走哪条路,不仅需要回答Commonware的关键问题“为什么”,还需要回答“要做什么”的问题

事实上,唯一能够通过捆绑包的就是普通数据——其他一切都基于对数据含义或指向的解释。你不能直接传递一个物体,但你可以做以下三件事之一:

1) 您可以将对象分解为其组成数据,如果另一端的对象知道相同类型的对象,则可以从序列化的数据组装克隆。这就是大多数常见类型通过bundle的方式

2) 可以传递不透明句柄。如果您在同一上下文中传递它(尽管有人可能会问为什么这么麻烦),那么您可以调用或取消引用该句柄。但若您通过绑定器将其传递到另一个上下文,它的文本值将是一个任意数(事实上,这些任意数从启动时开始按顺序计数)。您只能跟踪它,直到您将其传递回原始上下文,这将导致Binder将其转换回原始句柄,使其再次有用

3) 您可以传递一个神奇的句柄,例如文件描述符或对某些os/平台对象的引用,如果设置了正确的标志,Binder将为收件人创建指向同一资源的克隆,该克隆实际上可以在另一端使用。但这只适用于极少数类型的对象

最有可能的情况是,您传递类只是为了让另一端能够跟踪它并稍后将其返回给您,或者您将其传递到可以从序列化的组成数据创建克隆的上下文中。。。或者你正试图做一些行不通的事情,你需要重新思考整个方法。

对于我自己的问题,这是一个迟来的回答,但它一直受到关注,所以我觉得我必须解决它。这些答案大部分都是正确的,能够完美地完成工作。但是,这取决于应用程序的需要。此答案将用于描述此问题的两种解决方案。

应用 第一个是答案,因为这是这里谈论最多的答案。应用程序是放置需要引用上下文的实体的好对象。毫无疑问,`ServerSocket`需要一个上下文(用于文件I/o或简单的`ListAdapter`更新)。一、 就个人而言,我更喜欢这条路线。我喜欢应用程序,它们对于上下文检索很有用(因为它们可以是静态的,不可能导致内存泄漏),并且具有简单的生命周期。

服务 第二个问题。对于我的问题,“服务”实际上是更好的选择,因为这就是服务的设计目的: A Service is an application component that can perform long-running operations in the background and does not provide a user interface. 服务是一个应用程序组件,可以在中执行长时间运行的操作 后台,不提供用户界面。 服务是整洁的,因为它们有一个更明确的生命周期,更易于控制。此外,如果需要,服务可以在应用程序外部运行(即启动时)。这可能是一些应用程序所必需的,或者只是一个简单的功能。


这也不是一个完整的描述,但我为那些想进一步调查的人留下了文档链接。总的来说,
服务
对于我所需要的实例来说是最好的—将ServerSocket运行到我的SPP设备。

通过bundle发送对象的另一种方法是使用
bundle.putByteArray

示例代码

将数据库的对象放入捆绑包:

class FirstClass{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...

//When you want to start new Activity...
Intent dataIntent =new Intent(FirstClass.this, SecondClass.class);
            Bundle dataBundle=new Bundle();
            DataBean dataObj=new DataBean();
            dataObj.setDate();
            try {
                dataBundle.putByteArray("Obj_byte_array", object2Bytes(dataObj));

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();

            }

            dataIntent.putExtras(dataBundle);

            startActivity(dataIntent);
}
将对象转换为字节数组

/**
 * Converting objects to byte arrays
 */
static public byte[] object2Bytes( Object o ) throws IOException {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream( baos );
      oos.writeObject( o );
      return baos.toByteArray();
    }
从捆绑包中获取对象:

class SecondClass{
DataBean dataBean;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...

//Get Info from Bundle...
    Bundle infoBundle=getIntent().getExtras();
    try {
        dataBean = (DataBean)bytes2Object(infoBundle.getByteArray("Obj_byte_array"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
从字节数组获取对象的方法:

/**
 * Converting byte arrays to objects
 */
static public Object bytes2Object( byte raw[] )
        throws IOException, ClassNotFoundException {
      ByteArrayInputStream bais = new ByteArrayInputStream( raw );
      ObjectInputStream ois = new ObjectInputStream( bais );
      Object o = ois.readObject();
      return o;
    }

希望这对其他朋友有所帮助。

您也可以使用Gson将对象转换为JSONObject并将其传递给bundle。对我来说,这是我发现的最优雅的方式。我还没有测试它如何影响性能

在最初的活动中

Intent activity = new Intent(MyActivity.this,NextActivity.class);
activity.putExtra("myObject", new Gson().toJson(myobject));
startActivity(activity);
在下一个活动中

String jsonMyObject;
Bundle extras = getIntent().getExtras();
if (extras != null) {
   jsonMyObject = extras.getString("myObject");
}
MyObject myObject = new Gson().fromJson(jsonMyObject, MyObject.class);

我在寻找传递日期对象的方法时遇到了这个问题。在我的例子中,正如答案中所建议的那样,我使用了Bundle.putSerializable(),但对于原始文章中描述的DataManager这样复杂的事情,这是行不通的

我的建议是使用依赖注入,将DataManager绑定到一个单例作用域,并在需要的地方注入DataManager,这将产生与将DataManager放入应用程序或使其成为单例非常相似的结果。您不仅可以获得增加的可测试性的好处,而且还可以获得更干净的代码,而无需所有的锅炉板“在类和活动之间传递依赖项”代码。非常容易使用,而且新框架看起来也很有前景

可能的解决方案:

Bundle bundle = new Bundle();
bundle.putSerializable("key", new CustomObject());
类自定义对象:

class CustomObject implements Serializable{
 private SubCustomObject1 sc1;
 private SubCustomObject2 sc2;
}
子自定义对象:

class SubCustomObject1 implements Serializable{ }

class SubCustomObject2  implements Serializable{ }

使用束传递对象的另一种简单方法:

  • 在类对象中,使用键创建静态列表或其他数据结构
  • 创建对象时,使用键(即创建对象时的长时间戳)将其放入列表/数据结构中
  • 创建方法static getObject(长键)以从列表中获取对象
  • class CustomObject implements Serializable{
     private SubCustomObject1 sc1;
     private SubCustomObject2 sc2;
    }
    
    class SubCustomObject1 implements Serializable{ }
    
    class SubCustomObject2  implements Serializable{ }
    
    class Object implements Serializable{
        String firstName;
       String lastName;
    }
    
    Bundle bundle = new Bundle();
    Object Object = new Object();
    bundle.putSerializable("object", object);
    
    Object object = (Object) getArguments().getSerializable("object");