我需要通过一个捆绑包传递对该类进行大部分处理的类的引用。
问题在于它与意图或上下文无关,并且具有大量非原始对象。如何将类打包为可打包/可序列化的类并将其传递给startActivityForResult
?
我需要通过一个捆绑包传递对该类进行大部分处理的类的引用。
问题在于它与意图或上下文无关,并且具有大量非原始对象。如何将类打包为可打包/可序列化的类并将其传递给startActivityForResult
?
Answers:
弄清楚走哪条路不仅需要回答CommonsWare的关键问题“为什么”,还需要回答“到什么?”的问题。你在通过吗
现实情况是,唯一可以通过捆绑销售的商品是纯数据-其他所有内容都基于对数据含义或指向的解释。您不能从字面上传递对象,但是您可以做的是以下三件事之一:
1)您可以将对象分解成其构成数据,并且如果另一端对相同类型的对象有所了解,则可以从序列化数据中组装一个副本。这就是大多数常见类型通过包传递的方式。
2)您可以传递不透明的手柄。如果在相同的上下文(尽管可能会问为什么要打扰)中传递它,则可以调用或取消引用它。但是,如果您通过Binder将其传递到其他上下文,则其字面值将是任意数字(实际上,这些任意数字从启动起就按顺序计数)。除了跟踪它之前,您什么也不能做,除非将其传递回原始上下文,这将使Binder将其转换回原始句柄,使其再次有用。
3)您可以传递魔术句柄,例如文件描述符或对某些os / platform对象的引用,如果设置了正确的标记,则Binder将创建一个指向接收者相同资源的克隆,该克隆实际上可用于另一端。但这仅适用于极少数类型的对象。
最有可能的是,您只是传递您的类,以便另一端可以跟踪它并在以后将其返回给您,或者您将其传递给可以从序列化组成数据创建克隆的上下文...否则您正在尝试做一些行不通的事情,您需要重新考虑整个方法。
您还可以使用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);
您可以使用全局应用程序状态。
更新:
自定义,然后将其添加到您的AndroidManifest.xml中:
<application android:label="@string/app_name" android:debuggable="true" android:name=".CustomApplication"
然后在您的项目中有一个这样的类:
package com.example;
import android.app.Application;
public class CustomApplication extends Application {
public int someVariable = -1;
}
并且由于“ 可以从任何活动或服务通过getApplication()访问它 ”,因此您可以像这样使用它:
CustomApplication application = (CustomApplication)getApplication();
application.someVariable = 123;
希望有帮助。
您还可以使对象可序列化,并使用Bundle的getSerializable和putSerializable方法。
可能的解决方案:
Bundle bundle = new Bundle();
bundle.putSerializable("key", new CustomObject());
类CustomObject:
class CustomObject implements Serializable{
private SubCustomObject1 sc1;
private SubCustomObject2 sc2;
}
子自定义对象:
class SubCustomObject1 implements Serializable{ }
class SubCustomObject2 implements Serializable{ }
通过捆绑发送对象的另一种方法是使用bundle.putByteArray
示例代码
public class DataBean implements Serializable {
private Date currentTime;
public setDate() {
currentTime = Calendar.getInstance().getTime();
}
public Date getCurrentTime() {
return currentTime;
}
}
将DataBean的对象放入Bundle中:
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();
}
从Bundle中获取对象:
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;
}
希望这对其他伙伴有帮助。
1.一个非常直接且易于使用的例子,使对象通过工具Serializable。
class Object implements Serializable{
String firstName;
String lastName;
}
2.在捆绑中传递对象
Bundle bundle = new Bundle();
Object Object = new Object();
bundle.putSerializable("object", object);
3.从捆绑中获取传递的对象为可序列化对象,然后转换为对象。
Object object = (Object) getArguments().getSerializable("object");
这是对我自己的问题的一个非常迟来的答案,但是它一直在引起关注,所以我觉得我必须解决它。这些答案大多数都是正确的,可以完美地完成工作。但是,这取决于应用程序的需求。该答案将用于描述针对此问题的两种解决方案。
服务是一个应用程序组件,可以在其中执行长时间运行的操作 背景,并且不提供用户界面。服务是整洁的,因为它们具有更明确的生命周期,更易于控制。此外,如果需要,服务可以在应用程序外部运行(即在启动时)。这对于某些应用程序或仅是一项整洁的功能可能是必需的。
这不是一个完整的描述,但是我为想要进行更多调查的人留下了指向文档的链接。总体而言,Service
对于我需要的实例而言,效果更好-在我的SPP设备上运行ServerSocket。
我在寻找一种传递Date对象的方法时遇到了这个问题。就我而言,正如答案中所建议的那样,我使用了Bundle.putSerializable(),但这不适用于复杂的事情,如原始文章中所述的DataManager。
我的建议与将所述DataManager放入应用程序或使其成为Singleton的结果非常相似,是使用依赖注入并将DataManager绑定到Singleton范围,并在需要的地方注入DataManager。不仅获得了提高可测试性的好处,而且还获得了更简洁的代码,而没有所有样板代码“在类和活动之间传递依赖关系”代码。(Robo)Guice非常易于使用,新的Dagger框架看起来也很有希望。