我是新的Android开发人员,在开始提供项目列表详细信息的新活动时遇到问题。
我的第一项活动是列出智能手机上安装的所有应用程序。 当我单击此列表中的某个项目时,第二个活动将开始显示该项目的详细信息。
然而,我的onSaveInstanceState方法,允许我每次切换智能手机位置时都不会重新加载应用程序,似乎被发送到详细活动,并且它进入无限循环(或者由于序列化而非常长ByteBuffer中的位图。)
我的PInfo对象是包含所有应用程序信息(版本,名称,位图)的对象。
public class PInfo implements Serializable{
private static final long serialVersionUID = 1L;
private String appname = "";
private String pname = "";
private String versionName = "";
private int versionCode = 0;
private Bitmap icon ;
private static ByteBuffer dst;
private static byte[] bytesar;
public String getAppname() {
return appname;
}
public void setAppname(String appname) {
this.appname = appname;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public int getVersionCode() {
return versionCode;
}
public void setVersionCode(int versionCode) {
this.versionCode = versionCode;
}
public Bitmap getIcon() {
return icon;
}
public void setIcon(Bitmap icon) {
this.icon = icon;
}
private void writeObject(ObjectOutputStream out) throws IOException{
out.writeObject(appname);
out.writeObject(pname);
out.writeObject(versionName);
out.writeInt(versionCode);
out.writeInt(icon.getRowBytes());
out.writeInt(icon.getHeight());
out.writeInt(icon.getWidth());
int bmSize = icon.getRowBytes() * icon.getHeight();
if(dst==null || bmSize > dst.capacity())
dst= ByteBuffer.allocate(bmSize);
out.writeInt(dst.capacity());
dst.position(0);
icon.copyPixelsToBuffer(dst);
if(bytesar==null || bmSize > bytesar.length)
bytesar=new byte[bmSize];
dst.position(0);
dst.get(bytesar);
out.write(bytesar, 0, bytesar.length);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
appname=(String) in.readObject();
pname=(String) in.readObject();
versionName=(String) in.readObject();
versionCode= in.readInt();
int nbRowBytes=in.readInt();
int height=in.readInt();
int width=in.readInt();
int bmSize=in.readInt();
if(bytesar==null || bmSize > bytesar.length)
bytesar= new byte[bmSize];
int offset=0;
while(in.available()>0){
offset=offset + in.read(bytesar, offset, in.available());
}
if(dst==null || bmSize > dst.capacity())
dst= ByteBuffer.allocate(bmSize);
dst.position(0);
dst.put(bytesar);
dst.position(0);
icon=Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
icon.copyPixelsFromBuffer(dst);
//in.close();
}
我的列表活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_application_list);
if (savedInstanceState != null) {
apps = (ArrayList<PInfo>) savedInstanceState.getSerializable("apps");
} else {
apps = new ArrayList<PInfo>();
apps = getInstalledApps(false);
}
appAdapter = new AppAdapter(apps);
setListAdapter(appAdapter);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long index) {
AppAdapter appAdapter = new AppAdapter(apps);
PInfo app = appAdapter.getItem(position);
Intent intent = new Intent(ApplicationListActivity.this,ApplicationDetailActivity.class);
//intent.putExtra("app", app);
intent.putExtra("app_index", index);
startActivity(intent);
}
private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) {
ArrayList<PInfo> res = new ArrayList<PInfo>();
List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
for(int i=0;i<packs.size();i++) {
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
PInfo newInfo = new PInfo();
newInfo.setAppname(p.applicationInfo.loadLabel(getPackageManager()).toString());
newInfo.setPname(p.packageName);
newInfo.setVersionName(p.versionName);
newInfo.setVersionCode(p.versionCode);
Drawable d = p.applicationInfo.loadIcon(getPackageManager());
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
newInfo.setIcon(bitmap);
res.add(newInfo);
}
return res;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("apps", apps);
super.onSaveInstanceState(outState);
}
我的详细活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_application_detail);
//PInfo p = (PInfo)getIntent().getExtras().getSerializable("app");
PackageInfo p = getPackageManager().getInstalledPackages(0).get((int)getIntent().getExtras().getLong("app_index"));
appName = (TextView) findViewById(R.id.appName);
versionName = (TextView) findViewById(R.id.versionName);
detailIcon = (ImageView) findViewById(R.id.detailIcon);
appName.setText(p.applicationInfo.loadLabel(getPackageManager()).toString());
versionName.setText(p.versionName);
detailIcon.setImageDrawable(p.applicationInfo.loadIcon(getPackageManager()));
}
来自logCat的部分消息(只是无限循环的一部分;)):
10-31 15:06:53.065:D / dalvikvm(3406):GC_CONCURRENT释放0K,20%免费45150K / 55751K,暂停12ms + 8ms,总计32ms
10-31 15:06:53.065:D / dalvikvm(3406):WAIT_FOR_CONCURRENT_GC阻止了20ms
10-31 15:06:53.100:D / dalvikvm(3406):GC_CONCURRENT释放1013K,18%免费46177K / 55751K,暂停12ms + 3ms,总计33ms
10-31 15:06:53.100:D / dalvikvm(3406):WAIT_FOR_CONCURRENT_GC阻止了21ms
10-31 15:06:53.115:D / dalvikvm(3406):GC_FOR_ALLOC释放0K,18%免费46177K / 55751K,暂停13ms,总计13ms
10-31 15:06:53.115:I / dalvikvm-heap(3406):将堆(frag case)增长到47.644MB,用于2105798字节分配
10-31 15:06:53.145:D / dalvikvm(3406):GC_CONCURRENT释放1027K,16%免费47206K / 55751K,暂停12ms + 3ms,总计30ms
10-31 15:06:53.145:D / dalvikvm(3406):WAIT_FOR_CONCURRENT_GC阻止了16ms
10-31 15:06:53.160:D / dalvikvm(3406):GC_FOR_ALLOC释放0K,16%释放47206K / 55751K,暂停15ms,总计15ms
10-31 15:06:53.165:I / dalvikvm-heap(3406):将堆(frag case)增长到50.659MB,用于4213190字节分配
10-31 15:06:53.195:D / dalvikvm(3406):GC_CONCURRENT释放6664K,20%免费44656K / 55751K,暂停12ms + 3ms,总计32ms
10-31 15:06:53.195:D / dalvikvm(3406):WAIT_FOR_CONCURRENT_GC阻止了19ms
我希望我已经足够清楚,抱歉最终会出现拼写错误。
答案 0 :(得分:1)
最后,我的readObject和writeObject不适用于位图的序列化。我找到了另一种方法,但存在一些性能问题(返回列表需要4或5秒):Serializing and De-Serializing android.graphics.Bitmap in Java