2016-11-29 6 views
1

XML 파일을 선택하려면 Intent.ACTION_GET_CONTENT의 의도를 사용하십시오. onActivityResult() 내에서 asynctask를 실행하여이 XML 파일을 데이터베이스로 읽습니다.onActivityResult() 내에서 Asynctask 실행

오류 처리 및 예상 된 UI 변경으로 인해 앱이 계속 진행되기 전에 진행 표시 줄을 표시하도록 asynctask를 표시하고 싶습니다.

asynctask가 실행되는 동안 인 텐트가 만드는 선택기 대화 상자가 표시됩니다. 즉, 응용 프로그램이 여전히 onActivityResult() 블록에 있고 표시된 진행 대화 상자가 없습니다. onActivityResult()가 끝나면 onPostExecute()가 호출됩니다.

나는 또한 응용 프로그램 진행하기 전에 AsyncTask를 마감합니다) (갔지 사용하려고했지만, 행운과 ...

나는 내 부분에 잘못된 논리로 귀결 생각 ...

importDB가 자체 클래스 인 것을 제외하면 모든 활동이 하나의 활동에서 발생합니다.

의도는 ...

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); 

이 방법 startet입니다 ... 그리고 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는) ...

,691 다음과 같습니다
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()를 호출하고 progressbar를 표시하기 전에 onActivityResult()에서 대화 상자 창을 닫을 수 있습니까?

답변

0

기본적으로 을 차단해야합니다. 나는 시작시해서 ProgressDialog를 표시하고 완료되면 그것을 숨기고와 함께 AsyncTask를를 사용하는 것입니다 : 당신이 결정할 수

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

어쩌면 나는 조금 불투명했다. progressbar를 표시하려고 시도했지만 asynctask가 onPostExecute()에 도달 할 때까지 intent가 만든 파일 대화 상자 창이 열려 있기 때문에 onPreExecute 및 doInBackground() 중에 progressbar가 표시되지 않습니다. 재미있는 점은 progressbar.isShowing()이 true를 반환한다는 것입니다 ... – user1086500

+0

당신이 무슨 뜻인지 확실하지 않습니다. 일반적으로'startActivityForResult()'로 열린 액티비티는'onActivityResult'가 실행되기 바로 전에 닫힙니다 – injecteer

+0

저는 이것을 에뮬레이터 API 23과 안드로이드 6을 사용하는 samsung s6에서 시도했습니다. Thread.sleep을 내부에 넣었습니다 onActivityResult()에서 호출 된 asynctask에서 doInBackground()를 호출하면이 절전 모드에서 선택할 파일이있는 대화 상자가 표시됩니다. onAcitivtyResult()가 끝나면 활동/의도가 닫힌 것 같습니다 ... – user1086500