Friday 25 March 2016

serialization - How can I start a new Android activity without sending savedInstanceState?



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) savedInstanceState.getSerializable("apps");
} else {
apps = new ArrayList();

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 getInstalledApps(boolean getSysPackages) {

ArrayList res = new ArrayList();
List packs = getPackageManager().getInstalledPackages(0);
for(int i=0;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.


Answer



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


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...