4

数日間の絶望的な日々の後、私はついにほとんど実用的な例を作成しました。

目標: onCreateで、AsyncTaskでXMLファイルをダウンロードして解析し、進行状況ダイアログを表示し、UIを更新して、ダイアログを閉じます。

問題:向きが変わると、アクティビティが再開され、AsyncTaskはそれへの参照を失います。それについてはたくさんの質問やブログがあります。しかし、なぜこの特定のソリューションが機能しないのかわかりません。または、この場合、Androidがダイアログを処理する方法。

状態:アプリを起動すると、すべて問題ありません。デバイスを回転させたり、メニューから手動でタスクを再開したりできます。しかし、タスクが終了し、向きを再度変更すると、ダイアログが(期待どおりに)ポップアップし、他に何も起こりません。進行状況の変更、ダイアログの却下はありません。AsyncTaskは正常に終了します。

コード:

package com.test;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

public class Test extends TabActivity {
DownloadFileAsync task;
ProgressDialog   progressDialog;
static final int PROGRESS_DIALOG = 0;

private static Data      data;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {       
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    /* - Run from different locations bug - */
    //http://code.google.com/p/android/issues/detail?id=2373
    if (!isTaskRoot()) {
        final Intent intent = getIntent();
        final String intentAction = intent.getAction();
        if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
                intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
            finish();
        }
    }
    /* - /Run from different locations bug  */

    /* -------------- Tabs ---------------- */
    Resources res = getResources();
    TabHost mTabHost = getTabHost();
    mTabHost.addTab(mTabHost.newTabSpec("overview").setIndicator("MYTAB1",res.getDrawable(R.drawable.ic_tab_home)).setContent(R.id.tab1));      
    mTabHost.setCurrentTab(0);
    /* -------------- /Tabs --------------- */

    /* -------------- /Data --------------- */
    task = (DownloadFileAsync)getLastNonConfigurationInstance();
    if(task!= null) {
        task.setActivity(this);
    } else {
        if(data == null) {
            File datafile = this.getFileStreamPath("data.dat");
            if(datafile.exists()){
                //Log.d("log", "File exists!");
                try {
                    long time = System.currentTimeMillis();
                    ObjectInputStream obj = new ObjectInputStream(new FileInputStream(datafile));
                    data = (Data)obj.readObject();
                    obj.close();
                    Log.d("time", "loaded in:"+(System.currentTimeMillis()- time));

                    if(data.isUpToDate() || !isOnline()){
                        update();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    datafile.delete();
                    data = null;
                }
                //Log.d("log", "Passed?");
            }
        }       
        /* DEBUG if(data == null || !data.isUpToDate())*/ this.synchronize(); 
    }
    /* -------------- /Data --------------- */

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add("Synchronize").setIcon(R.drawable.ic_menu_refresh);     
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    synchronize();
    return super.onOptionsItemSelected(item);
}

@Override
public Object onRetainNonConfigurationInstance() {
    if(task != null) task.setActivity(null);      
    return(task);
}

protected Dialog onCreateDialog(int id) {
    switch (id) {
    case PROGRESS_DIALOG:
        progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Aktualizuji ...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);            
        //progressDialog.show();            
        return progressDialog;
    default:
        return null;
    }
}

public void update() {

}

private void onTaskCompleted() {
    task = null;        
    dismissDialog(PROGRESS_DIALOG);     
    Log.d("tok","Task.onComplete");
    update();       
}

public void synchronize(){
    if(isOnline()) {
        showDialog(PROGRESS_DIALOG);
        progressDialog.setProgress(0); // <-- this is the last time progressDialog updates
        task = new DownloadFileAsync(this);
        task.execute();
    }
}

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(WaspActivity.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    }
    return false;
}

private static class DownloadFileAsync extends AsyncTask<String, String, String> {
    private Data tempData;
    private Test activity;
    private int progress = 0;
    private File metafile;
    private File tempDir;
    private FileOutputStream fos;

    public DownloadFileAsync(Test activity) {
        this.setActivity(activity);


        ... some more init ...
    }

    public void setActivity(Test activity) {
        this.activity = activity;           
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        tempData = new Data();
    }

    @Override
    protected String doInBackground(String... aurl) {
        try {

        ... some heavy load  ...
        //this.progress = someValue;                

        } catch (Exception e) {
            Log.d("Error", "Error while processing files. Code:"+e.getMessage());
            e.printStackTrace();
        }

        //Log.d("time","Task "+(System.currentTimeMillis() - time));
        return null;

    }
    protected void onProgressUpdate(String... progress) {            
        if(activity != null) activity.progressDialog.setProgress(this.progress);
    }

    @Override
    protected void onPostExecute(String unused) {
        data = tempData;
        tempData = null;
        if(activity != null) {
            activity.onTaskCompleted();
            activity = null;
        }
    }
}

}
4

3 に答える 3

6

昨日、保持されたを使用して構成変更を処理する方法を説明するブログ投稿を書きましたFragment

TL; DRは、AsyncTask内部のホストを使用しFragment、を呼び出し、保持されたを介しての進行状況/結果を報告します。setRetainInstance(true)FragmentAsyncTaskActivityFragment

于 2013-04-30T16:49:44.053 に答える
2

これをマニフェストのテストアクティビティに追加します

android:configChanges="orientation|keyboardHidden"></activity>

これをテストクラスに入れます

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}
于 2012-03-09T08:42:31.827 に答える
0

マニフェストファイルのタグを入れandroid:screenOrientation="portrait"ます。<activity />その後、これらの行onPreExecute()をasyncTaskのprotectedvoidメソッドに入れます。

dialog.setMessage("Please wait.....");
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();
于 2012-03-09T09:03:59.363 に答える