Question

I'm a new Android developer and I have a problem while starting a new activity which provide details of an item list.

My first activity is listing all the applications installed on the smartphone. When I click on an item of this list, the second activity starts displaying the detail of the item.

However, my onSaveInstanceState method, which allows me to not reload the applications each time I switch the smartphone position, seems to be sent to the detail activity and it enters in an infinite loop (or very very long because of the serialization of the bitmap in the ByteBuffer).

My PInfo object is the object containing all the application information (version, name, bitmap).

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();
}

My list activity:

@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);
}

My detail activity:

@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()));
    
    
}

The partial message from the logCat (just a piece of the infinite loop ;) ):

10-31 15:06:53.065: D/dalvikvm(3406): GC_CONCURRENT freed 0K, 20% free 45150K/55751K, paused 12ms+8ms, total 32ms

10-31 15:06:53.065: D/dalvikvm(3406): WAIT_FOR_CONCURRENT_GC blocked 20ms

10-31 15:06:53.100: D/dalvikvm(3406): GC_CONCURRENT freed 1013K, 18% free 46177K/55751K, paused 12ms+3ms, total 33ms

10-31 15:06:53.100: D/dalvikvm(3406): WAIT_FOR_CONCURRENT_GC blocked 21ms

10-31 15:06:53.115: D/dalvikvm(3406): GC_FOR_ALLOC freed 0K, 18% free 46177K/55751K, paused 13ms, total 13ms

10-31 15:06:53.115: I/dalvikvm-heap(3406): Grow heap (frag case) to 47.644MB for 2105798-byte allocation

10-31 15:06:53.145: D/dalvikvm(3406): GC_CONCURRENT freed 1027K, 16% free 47206K/55751K, paused 12ms+3ms, total 30ms

10-31 15:06:53.145: D/dalvikvm(3406): WAIT_FOR_CONCURRENT_GC blocked 16ms

10-31 15:06:53.160: D/dalvikvm(3406): GC_FOR_ALLOC freed 0K, 16% free 47206K/55751K, paused 15ms, total 15ms

10-31 15:06:53.165: I/dalvikvm-heap(3406): Grow heap (frag case) to 50.659MB for 4213190-byte allocation

10-31 15:06:53.195: D/dalvikvm(3406): GC_CONCURRENT freed 6664K, 20% free 44656K/55751K, paused 12ms+3ms, total 32ms

10-31 15:06:53.195: D/dalvikvm(3406): WAIT_FOR_CONCURRENT_GC blocked 19ms

  1. I want to know what is happening when I start my detail Activity?
  2. Is this loop serializing all the bitmap from all the applications into the ByteBuffer?
  3. How can I start my detail Activity without starting this loop?

I hope I have been clear enough, sorry for eventuals spelling errors.

Was it helpful?

Solution

Finally, it was my readObject and writeObject which were not adapted for the serialization of the bitmap. I found an alternative way, but there is some performance issue (4 or 5 second to return to the list) : Serializing and De-Serializing android.graphics.Bitmap in Java

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top