문제

필사적 인 날짜가 아마도 마침내 거의 작업 예제를 만들었습니다.

목표 : Asynctask에서 다운로드하고 parsexml 파일을 다운로드하고, 진행률 대화 상자를 표시하고, UI를 업데이트하고 대화 상자를 닫으십시오.

이 문제점 : 방향이 변경되면 활동이 다시 시작되고 Asynctask는 참조를 잃습니다.그것에 대해 많은 질문과 블로그가 있습니다.그러나이 특별한 해결책이 작동하지 않는지 알아낼 수 없습니다.또는이 경우 안드로이드가 대화 상자를 처리하는 방법.

상태 : 앱을 시작하면 모든 것이 괜찮습니다.장치를 회전시킬 수 있으며 메뉴를 통해 수동으로 작업을 다시 시작할 수 있습니다.그러나 작업이 끝나고 방향을 다시 변경하면 (예상대로) 다른 일이 발생하지 않습니다.진행률이 변경되지 않고 대화 상자가 해산되지 않습니다.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;
        }
    }
}

}
.

도움이 되었습니까?

해결책

Yesterday, I wrote a blog post which describes handling configuration changes using retained Fragments.

The TL;DR is to use host your AsyncTask inside a Fragment, call setRetainInstance(true) on the Fragment, and report the AsyncTask's progress/results back to it's Activity through the retained Fragment.

다른 팁

add this to Test activity in manifest

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

and put this in your test class

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
}

Put android:screenOrientation="portrait" in your <activity /> tag of manifest file. After doing that, put these lines in protected void onPreExecute() method of asyncTask:

dialog.setMessage("Please wait.....");
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
            dialog.show();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top