2016-11-29 28 views
1

使用intent.ACTION_GET_CONTENT來選擇XML文件。在onActivityResult()中,我啓動一個asynctask將這個XML文件讀入數據庫。在onActivityResult()中啓動Asynctask()

我想要的AsyncTask顯示一個進度,以確保它是由於錯誤處理和預期的UI變化的應用程序進行之前完成。

只要執行了asynctask,就會顯示意圖創建的選擇器對話框 - 即應用程序仍在onActivityResult()塊中,並且沒有顯示進度對話框。 onPostExecute()被稱爲AFTER onActivityResult()結束。

我也嘗試過使用獲得()的應用程序進行前,進行的AsyncTask完成,但沒有運氣...

我認爲它歸結爲錯誤的邏輯在我的部分...

一切都在,只是importDB一個活動發生的是一類自身的。

的意圖是startet這樣...

intent = new Intent(Intent.ACTION_GET_CONTENT); 
intent.addCategory(Intent.CATEGORY_OPENABLE); 
intent.setType("text/xml"); 
startActivityForResult(Intent.createChooser(intent, "Select XML"), RC_IMPORT_FILE); 

...和onActivityResult()看起來像這樣...

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (resultCode) { 
     case Activity.RESULT_OK: 
      switch (requestCode) { 
       case RC_IMPORT_FILE: 
        Uri uri = data.getData(); 
        if (data != null) { 
         importDB(new File(uri.toString()), uri, false); 
        }; 
       break; 
     ... more switch statements... 
    } 
} 

...和importDB看起來是這樣的。 ..

private void importDB(File file, Uri uri, boolean xmlRaw, Context context) { 
    int error = 0; 

    ImportDataBase importDataBase = new ImportDataBase(); 
    importDataBase.setContext(this); 
    importDataBase.setUri(uri); 
    importDataBase.xmlRaw(xmlRaw); 
    try { 
     importDataBase.execute("ImportDB").get(); 
    } catch (ExecutionException ee) { 
     logException(TAG, "importDB", ee); 
     error = 1; 
    } catch (InterruptedException ie) { 
     logException(TAG, "importDB", ie); 
     error = 2; 
    } 
} 

...和異步任務(ImportDataBase)看起來像這樣...

import android.app.ProgressDialog; 
import android.content.Context; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.widget.Toast; 
import java.io.InputStream; 

public class ImportDataBase extends AsyncTask<String, Integer, String> { 

private static final String TAG = "ImportDataBase"; 

private Context context; 
private ProgressDialog progressDialog; 

private Uri uri = null; 
private InputStream xmlStream = null; 

private XMLParser xmlParser; 
private boolean xmlRaw = true; 
private int errorCode = 0; 

public void xmlRaw(boolean xmlRaw) { 
    this.xmlRaw = xmlRaw; 
} 

public void setUri(Uri uri) { this.uri = uri; } 
public void setInputStream(InputStream inputStream) { this.xmlStream = inputStream; } 
public void setContext(Context context) { 
    this.context = context; 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 
    progressDialog = this.context; 
    progressDialog.setCancelable(false); 
    progressDialog.setMessage("Please wait..."); 
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    progressDialog.show(); 
    xmlParser = new XMLParser(); 
    xmlParser.xmlRaw(xmlRaw); 
} 

@Override 
protected String doInBackground(String... params) { 
    String result = "0"; 
    int error = 0; 
    InputStream inputStream = null; 
    try { 
     if (uri != null) inputStream = context.getContentResolver().openInputStream(uri); 
      else inputStream = this.xmlStream; 
    } catch (Exception e) { 
     result = "1000"; 
    } 

    if (error == 0) { 
     try { 
      xmlParser.readXML(inputStream); 
     } catch (NullPointerException npe) { 
       result ="10"; 
     } catch (Exception e) { 
       result ="10"; 
     } 

    } else result = "31"; 

    switch (xmlParser.getError()) { 
     case 1 : result = "10"; break; // XML Parser error 
     case 2 : result = "15"; break; // URLERROR; 
     case 3 : result = "30"; break; // IOFileError 
     case 4 : result = "31"; break; // FileError; 
     case 5 : result = "32"; break; // FileDoesNotExists; 
     default : result = "0"; 
    } 

    try { 
     inputStream.close(); 
    } catch (Exception e) { 
    } 
    return result; 
} 

@Override 
protected void onPostExecute(String string) { 
    super.onPostExecute(string); 
    String error = ""; 
    if (Integer.valueOf(string) > 0) { 
     switch (Integer.valueOf(string)) { 
      case 1: 
       error = "You need to update the app to the newest version!"; 
       errorCode =1; 
      break; 
      case 10 : 
       error = "XML parser error! Wrong file?"; 
       errorCode =10; 
      break; 
      case 15 : 
       error = "Wrong URL!"; 
       errorCode =15; 
      break; 
      case 30 : 
       error = "File read/Write error!"; 
       errorCode =30; 
       break; 
      case 31 : 
       error = "File error"; 
       errorCode =31; 
       break; 
      case 32 : 
       error = "File does not exsits!"; 
       errorCode =32; 
       break; 
      case 99 : 
       error = "Unknwon XML parser error!"; 
       errorCode =99; 
       break; 
      case 100: 
       error = "Database error! Retry or reinstall app!"; 
       errorCode =100; 
      break; 
      case 1000: 
       error = "Unknown error!"; 
       errorCode =1000; 
      break; 
      default: 
       error = "Unknwon error!"; 
     } 
     Toast.makeText(context, error, Toast.LENGTH_SHORT).show(); 
    } 
    if (progressDialog.isShowing()) progressDialog.dismiss(); 
} 

public int getError() { 
    return this.errorCode; 
} 

@Override 
protected void onCancelled() { 
    super.onCancelled(); 
} 
} 

我如何可以使應用程序等待的AsyncTask完成任何建議?在我調用importDB()並希望顯示進度條之前,是否可以關閉onActivityResult()中的對話窗口?

回答

0

基本上你應該永遠阻止任何東西。我會用一用的AsyncTask在啓動時顯示ProgressDialog和隱藏它完成時:

private ProgressDialog progressDialog; 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    // blahblah 
        if (data != null) { 
         new ImportTask(new File(uri.toString()), uri).execute(); 
        } 
    // blahblah 
} 

class ImportTask extends AsyncTask<Void, Void, Void> { 
    private File file; 
    private Uri uri; 

    ImportTask(File file, Uri uri){ 
    this.file = file; 
    this.uri = uri; 
    } 

    @Override 
    protected void onPreExecute() { 
    progressDialog.show(); 
    } 

    @Override 
    protected Void doInBackground(Void... voids) { 
    importDB(file, uri, false); 
    return null; 
    } 

    @Override 
    protected void onPostExecute(Void res) { 
    progressDialog.hide(); 
    }  
} 

這種方式,你可以決定做其他的東西在importDB()期間並​​行運行。

+0

也許我有點不清楚。我試圖顯示一個進度條,但是因爲意圖創建的文件對話框窗口打開,直到asynctask到達onPostExecute(),在onPreExecute和doInBackground()過程中從不顯示進度條。有趣的是,progressbar.isShowing()返回true ... – user1086500

+0

不確定你的意思。通常用'startActivityForResult()'打開的活動在執行'onActivityResult'之前關閉 – injecteer

+0

我已經在模擬器API 23和我的手機中使用了android 6的samsung s6。我已經把Thread.sleep放入了內部在onActivityResult()中調用的asynctask中的doInBackground(),並在此睡眠期間顯示具有可供選擇的文件的對話框。在onAcitivtyResult()完成後,似乎活動/意圖已關閉... – user1086500