2013-12-20 126 views
1

我正面臨着我的異步任務的問題。我有一些正常的操作要在後臺完成,並在完成後查看結果,但UI凍結,儘管我的代碼在doinbackground塊內。請幫幫我!異步任務凍結UI

下面是我的代碼。

class DownloadFileFromURL extends AsyncTask<String, Void, String> { 

    /** 
    * Before starting background thread Show Progress Bar Dialog 
    * */ 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pd = ProgressDialog.show(Interface.this, null, "Loading...", true); 
    } 

    /** 
    * Downloading file in background thread 
    * */ 
    @Override 
    protected String doInBackground(String... f_url) { 

     // 

     // Toast.makeText(getApplicationContext(), "Executing", 
     // 3000).show(); 

     runOnUiThread(new Runnable() { 
      public void run() { 

       Calculate(); 

      } 
     }); 

     return null; 
    } 

    /** 
    * Updating progress bar 
    * */ 
    protected void onProgressUpdate(String... progress) { 
     // setting progress percentage 

    } 

    /** 
    * After completing background task Dismiss the progress dialog 
    * **/ 
    @Override 
    protected void onPostExecute(String file_url) { 

     pd.dismiss(); 

    } 

} 



private void Calculate() 

{ 

    curs = mDb.query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_Common 
      + "=" + "?", new String[] { From[xxxto] + From[xxxfrom] }, 
      null, null, null); 
    cursD = mDb.query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_Common 
      + "=" + "?", new String[] { From[xxxfrom] + From[xxxto] }, 
      null, null, null); 

    curs.moveToFirst(); 

    cursD.moveToFirst(); 

    double selection = curs.getDouble(curs 
      .getColumnIndex(MyDbHelper.COL_Currone)); 

    double selection2 = cursD.getDouble(cursD 
      .getColumnIndex(MyDbHelper.COL_Currone)); 

    Long myNum = Long.parseLong(valval.getText().toString().trim()); 

    double myNum3 = Double.parseDouble(new DecimalFormat("#.######") 
      .format(myNum * selection2)); 

    valval2.setText(String.valueOf(myNum3)); 


/* 
    Cursor B = mDb 
      .query(MyDbHelper.TABLE_NAME, columns, MyDbHelper.COL_CurrFavor 
        + "=? And " + MyDbHelper.COL_Currsecond + "=?", 

        new String[] { "YES", "EUR" }, null, null, null); 

    */   

    Cursor B = mDb.rawQuery("select * from " 
      + MyDbHelper.TABLE_NAME + " where " + MyDbHelper.COL_CurrFavor + " = ? AND " 
      + MyDbHelper.COL_Currsecond + " = ?", new String[] { "YES", "EUR" }); 




    for (int s = 0; s < 4 - 1; s++) 

    { 
     B.moveToPosition(s); 

     String ZVZV = B.getString(0); 

     int BSBS = B.getInt(9); 

     Cursor curcur = mDb.query(MyDbHelper.TABLE_NAME, columns, 
       MyDbHelper.COL_Common + "=" + "?", 
       new String[] { From[xxxfrom] + From[BSBS - 1] }, null, 
       null, null); 

     curcur.moveToFirst(); 

     double calcal = curcur.getDouble(6); 

     ContentValues args = new ContentValues(); 

     double formattedNumber = Double.parseDouble(new DecimalFormat(
       "#.######").format(myNum * calcal)); 

     args.put(MyDbHelper.COL_Currsum, formattedNumber); 

     mDb.update(MyDbHelper.TABLE_NAME, args, "_id =" + ZVZV, null); 

    } 

    cursm.requery(); 



} 

這裏是在logcat的錯誤:

4月12日至20日:41:38.469:E/AndroidRuntime(440):android.view.ViewRoot $ CalledFromWrongThreadException:由僅引起的創建視圖層次結構的原始線程可以觸及其視圖。

另外我運行它使用:new DownloadFileFromURL2()。execute(「」);

回答

5

不要不要不要爲此在AsyncTask

runOnUiThread(new Runnable() { 
     public void run() { 

每個方法在AsyncTaskUI Thread運行,除了doInBackground()。在doInBackground()(您的計算,網絡操作等)中執行您的工作,然後從中獲得結果並通過調用publishProgress()更新onProgressUpdate()中的UI,或者如果後臺工作完成,則返回結果到onPostExecute(),您可以在那裏更新。

如果這樣不能解決您當前的問題,請發佈您如何致電任務...希望不要與.get()

編輯

此外,你應該看看文檔再次,你實際上並沒有經過什麼doInBackground().execute()

new DownloadFileFromURL2().execute(""); 

String,所以你可以改變第一param的申報要求Void

class DownloadFileFromURL extends AsyncTask<Void, Void, String> { 

,並沒有通過任何東西

new DownloadFileFromURL2().execute(); 

,除非你在以後更新此計劃。您還沒有從doInBackground()通過onPostExecute()任何與

return null; 

,所以你可以改變它取params。所以現在我們有

class DownloadFileFromURL extends AsyncTask<Void, Void, Void> { 

@Override 
protected void onPostExecute(Void result) { 

,並再次你有你的onProgressUpdate()採取任何params在任務類聲明(第二param

class DownloadFileFromURL extends AsyncTask<Void, Void, Void> { 

所以它應該像

protected void onProgressUpdate(Void... progress) { 
    // setting progress percentage 

} 

當然,這些都取決於您計劃通過它們的方式,在從Calculate()方法獲得結果後,您需要通過某些方法更新UI

+0

感謝您提供寶貴的信息。我試圖刪除runnable,但是由於附加到主要問題,我得到了錯誤。 –

+1

因爲您還沒有從'Calculate()'方法中刪除'UI'東西('Toasts'等) – codeMagic

+0

OK我會嘗試修改代碼,這取決於新的方法,並刪除doInbackground之外的不必要的UI內容。將更新你有點:)謝謝你的幫助! –

1

這是你犯錯的地方。

runOnUiThread(new Runnable() { 
      public void run() { 

       Calculate(); 

      } 
     }); 

這裏您要在UI線程中再次調用Calculate()方法。這就是爲什麼你的應用程序凍結。請致電,電話號碼doInBackground()

+1

不! ''Calculate()'做'UI'的東西,所以這將創建更多的錯誤,從背景'線程' – codeMagic

+1

UI的東西應該從該方法中刪除。並把它們放在onProgressUpdate()或onPostExecute() – Shashika

1

你在UI線程上調用了Calculate(),它肯定會凍結UI。 從calculate()中移除所有Ui內容,並在Async中直接調用它。