0

私は新しい Android 開発者ですが、アイテム リストの詳細を提供する新しいアクティビティを開始する際に問題が発生します。

私の最初のアクティビティは、スマートフォンにインストールされているすべてのアプリケーションを一覧表示することです。このリストのアイテムをクリックすると、2 番目のアクティビティがアイテムの詳細の表示を開始します。

ただし、スマートフォンの位置を切り替えるたびにアプリケーションをリロードしないようにする onSaveInstanceState メソッドは、detail アクティビティに送信されたようで、無限ループに入ります (または、ビットマップのシリアル化のために非常に長くなります)。 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 が 20 ミリ秒ブロックされました

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 が 21 ミリ秒ブロックされました

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 ケース) を 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 が 16 ミリ秒ブロックされました

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 ケース) を 4213190 バイトの割り当て用に 50.659MB に拡張します

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 が 19 ミリ秒ブロックされました

  1. 詳細アクティビティを開始したときに何が起こっているか知りたいですか?
  2. このループは、すべてのアプリケーションからのすべてのビットマップを ByteBuffer にシリアライズしていますか?
  3. このループを開始せずに詳細アクティビティを開始するにはどうすればよいですか?

最終的なスペルミスをお詫びします。

4

1 に答える 1

1

最後に、ビットマップのシリアル化に適合しなかったのは私の readObject と writeObject でした。別の方法を見つけましたが、いくつかのパフォーマンスの問題があります (リストに戻るのに 4 または 5 秒): Serializing and De-Serializing android.graphics.Bitmap in Java

于 2013-11-04T12:48:13.140 に答える