2

私は、とを持っているアクティビティを持っていProgressBarます。タスクの実行中に画面が完全に1つの向きになると、3つすべてが更新されますが、ImageViewTextViewが表示されず、画面の向きは、ある向きから別の向きに変わります。AsyncTaskImageViewTextViewProgressBar

attachanddetachメソッドをタスクに追加し、 andを使用してが破棄されretainNonConfigurationInstanceたときにタスクを返すために使用しても効果はありませんでした。ActivitygetLastNonConfigurationInstanceAsyncTask

MyActivity は次のようになります。

    static final String TAG="ImageUpdateActivity";
TextView txt_currentOp;
ImageView img_currentOp;
ImageUpdatingTask task;
CustomProgressBar updatebar;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_imageupdate);
    txt_currentOp=(TextView)findViewById(R.id.txt_currentOp);
    img_currentOp=(ImageView)findViewById(R.id.img_updateOp);
    updatebar=(CustomProgressBar)findViewById(R.id.progressbar_update);
    String filename=getIntent().getStringExtra("pathName");
    task=(ImageUpdatingTask)getLastNonConfigurationInstance();
    if(task!=null)
    {
        task.attach(this);
        if(task.getStatus()==AsyncTask.Status.RUNNING)
        {   
            Log.d(TAG, "The progress description is: "+task.getProgressDesc());
            txt_currentOp.setText(task.getProgressDesc());
            img_currentOp.setImageBitmap(task.getProgressBitmap());
            updatebar.setProgress(task.getProgress());
        }
    }
    else
    {
        task=new ImageUpdatingTask(this);
        task.execute(filename);
    }
}

public Object retainNonConfigurationInstance()
{
    task.detach();
    return task;
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        if(task.getStatus()!=AsyncTask.Status.FINISHED)
        {
            task.cancel(true);
            task=null;
        }
        Intent i=new Intent(this,ImagePreviewActivity.class);
        startActivity(i);
    }
    return super.onKeyDown(keyCode, event);
}

doInBackgroundこれは、メソッドから進行状況を更新する方法です。

 int progress=0;
 Bitmap progressBitmap=null;
 String progressDesc=null;

グローバル変数です。

 mOperation=BITMAP_TO_PIX;
    progressDesc=getValueFromOperation(mOperation);
    Pix pix=convertBitmapToPix(bitmap);
    mOperation=CONVERT_TO_8;
    progressDesc=getValueFromOperation(mOperation);
    Pix pix2=convertOperation(pix);
    temp=pix2.copy();
    tempImg=convertPixToBitmap(temp);
    progressBitmap=tempImg;
    temp=null;
    progress+=10;//60
    publishProgress(tempImg);

そして、私はpublishProgress次を使用します:

   @Override
protected void onProgressUpdate(Bitmap... values) {
// TODO Auto-generated method stub
    super.onProgressUpdate(values);
    int oldOperation=0,oldProgress=0;
    if(mOperation!=oldOperation)
    {
        String progressText=getValueFromOperation(mOperation);
        Log.d(TAG, progressText);
        activity.txt_currentOp.setText(progressText);
        oldOperation=mOperation;
    }
    if(oldProgress!=progress)
    {
        Log.d(TAG,"Update the progress: "+progress);
        activity.updatebar.setProgress(progress);
        oldProgress=progress;
    }

    activity.img_currentOp.setImageBitmap(values[0]);
}

そして、Activity は、コンストラクターを使用してタスクに渡されます。

  public ImageUpdatingTask(ImageUpdateActivity activity)
{
    this.activity=activity;
}

AsyncTaskと の間の相互作用を処理するメソッドは次のActivityとおりです。

   public void attach(ImageUpdateActivity activity)
{
    this.activity=activity;
}

public void detach()
{
    activity=null;
}

    public int getProgress()
{
    return progress;
}

public Bitmap getProgressBitmap()
{
    return progressBitmap;
}

public String getProgressDesc()
{
    return progressDesc;
}
4

1 に答える 1

2

向きが変わると、アクティビティが破棄されて再作成されます。フラグメントはアクティビティによってホストされます。

デフォルトでは、構成の変更が発生すると、フラグメントは親のアクティビティとともに破棄され、再作成されます。Fragments を呼び出すsetRetainInstance(true)と、この破棄と再作成のサイクルをバイパスでき、アクティビティが再作成されたときにフラグメントの現在のインスタンスを保持するようシステムに通知します。

public void setRetainInstance (boolean retain)

Added in API level 11
Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack. If set, the fragment lifecycle will be slightly different when an activity is recreated:

onDestroy() will not be called (but onDetach() still will be, because the fragment is being detached from its current activity).
onCreate(Bundle) will not be called since the fragment is not being re-created.
onAttach(Activity) and onActivityCreated(Bundle) will still be called.

推奨される回避策については、このブログを確認してください。インターフェイスをアクティビティへのコールバックとして使用します。

http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

同じソースコードは次の場所で入手できます。

https://github.com/alexjlockwood/worker-fragments

ブログより引用

イベントの流れ

MainActivity が初めて起動すると、TaskFragment がインスタンス化され、Activity の状態に追加されます。TaskFragment は AsyncTask を作成して実行し、TaskCallbacks インターフェイスを介して、進行状況の更新と結果を MainActivity にプロキシします。構成の変更が発生すると、MainActivity は通常のライフサイクル イベントを通過し、作成されると新しい Activity インスタンスが onAttach(Activity) メソッドに渡されるため、TaskFragment はその後でも現在表示されている Activity インスタンスへの参照を常に保持します。構成の変更。結果として得られる設計は、シンプルで信頼性の高いものです。アプリケーション フレームワークは、Activity インスタンスが破棄されて再作成されるときに、Activity インスタンスの再割り当てを処理します。

于 2013-11-13T10:25:58.293 に答える