2015-06-19 28 views
0

我遇到了runOnuiThread和AsyncTask一起調用的問題。RunonUI Thread在Android中執行一個AsynTask從執行到完成

我的AsynchTask通過runOnUIThread調用獲取數據來填充listView。 即使用戶界面不太好時,這個Asych Task也可以獲取數據。它從UI屏幕開始運行,直到應用程序註銷。 現在來自此任務的數據只能填充特定的列表視圖。 現在,如果我使用調用executeOnExecutor調用AsynchTask從另一個視圖調用另一個異步任務,則異步任務不會強制執行。它鎖定了。 如果我註釋掉永遠不會結束的AsychTask的代碼,稱爲Receiver ..那麼所有UI的listview都會被填充,並且沒有Asych Task鎖定。 此Receiver在REST API調用上等待返回響應,但由於我通過executeonExecutor調用運行,因此它應該是並行處理。 我需要讓接收器始終運行,因爲這是我的應用程序的一個組成部分。 我可以在這裏使用什麼策略來解決這個問題。 這裏是我的代碼片段。

public class Receiver { 
    private final static String QUEUE_NAME = "hello"; 

    private String m_ErrorMessage; 
    private IRunOnUIThreadCallback iRunOnUIThreadCallback; 
    private Send m_Received; 
    private int m_TimeoutDuration;//how long the reading of new message waits in milli seconds 

    public void SetCallback(IRunOnUIThreadCallback runOnUIThreadCallback) 
    { 
     iRunOnUIThreadCallback = runOnUIThreadCallback; 
    } 
    public void SetTimeoutDuration(int timeout) 
    { 
     m_TimeoutDuration = timeout; 
    } 
    public void StartReceiver(Send receiverInfo) 
    { 
     String receivedInfo = null; 
     try { 
      new ReceiveInfo().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, receiverInfo); 
     } 
     catch(Exception exp) 
     { 
      m_ErrorMessage = exp.getMessage(); 
     } 
    } 
    private class ReceiveInfo extends AsyncTask<Send, Void, Send> 
    { 
     //initiate vars 
     public receive() { 
      super(); 
      //my params here 
     } 
     protected Message doInBackground(Send... receiverInfo) 
     { 
          Send recv=null; 
      try { 

       PreferenceSingleton single = PreferenceSingleton.getInstance(); 
       final User user = single.getUser(); 
       final SvcApi svc = LoginAuthSvc.init(); 


       Send send=(Send)receiverInfo[0]; 
       send.setUserId(user.getUsername()); 
       //dxbrem 
       while (true) { 

        recv=svc.receive(send); 
        String str= recv.get(); 
        if ((str == null || (str.trim().length() == 0))) { 
         continue; 
        } 

        //DJ uncomment 
        iRunOnUIThreadCallback.RunAfterIsReceived(recv); 
        //messages.add(message); 
        System.out.println(" [x] Received '" + recv + "'"); 

       } 

      }catch(Exception exp) 
      { 
       m_ErrorMessage = exp.getMessage(); 
      } 

      return recv; 
     } 
    } 
    public String getErrorMessage() { 
     return m_ErrorMessage; 
    } 
} 

public interface IRunOnUIThreadCallback { 
    public void RunAfterIsReceived(ByteSent m); 
    public void RunAfterIsReceived(Send m); 
} 

處理這個..具有下面的代碼和

public class MainFragment extends Fragment implements MFragment.OnFragmentInteractionListener, IRunOnUIThreadCallback { 

    private Receiver mReceiver; 

    public void SetUICallbackOnMessageReceiver() 
     { 
      mReceiver.SetCallback(this); 
     } 

    private void callRunUIThread(final SentInfo m) { 
      getActivity().runOnUiThread(new Runnable() { 
       public void run() { 
        if (m!= null) { 
         mGridArray.add(message); 
         if (mListAdapter != null) { 
          mListAdapter.notifyDataSetChanged(); 
          mListView.setSelection(mListAdapter.getCount()); 
          mListView.smoothScrollToPosition(mListAdapter.getCount()); 
         } 
        } 
       } 
      }); // end of runOnUiThread 
     } 

    @Override 
     public void RunAfterIsReceived(ByteSent m) { 

     } 

     @Override 
      public void RunAfterIsReceived(Sent m) { 
       SentInfo m= new SentInfo(false, recv.getInfo()); 
       callRunUIThread(msg); 
      } 

mListAdapter是ListAdapater mListView是ListView的

這裏是AsynchTask代碼

import android.app.Activity; 
import android.app.Fragment; 

import android.content.Context; 
import android.os.AsyncTask; 
import android.util.Log; 



import java.util.concurrent.Callable; 
import java.util.concurrent.Executor; 

public class CallableTask<T> extends AsyncTask<Void,Double,T> { 

    private static final String TAG = CallableTask.class.getName(); 





    public static <V> void invoke(Callable<V> call,Activity activity, TaskCallback<V> callback){ 

     new CallableTask<V>(activity,call, callback).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
    } 




    private Callable<T> callable_; 
    private AsyncTask<Void, Void, String> asyncTask_; 
    private Context context; 
    private Activity activity; 
    private Fragment fragmentActivity; 
    private android.support.v4.app.Fragment dynamicFragment; 

    private TaskCallback<T> callback_; 

    private Exception error_; 

    public CallableTask(Fragment actvy,Callable<T> callable, TaskCallback<T> callback) { 
     callable_ = callable; 
     callback_ = callback; 
     fragmentActivity=actvy; 
    } 

    public CallableTask(Activity actvy,Callable<T> callable, TaskCallback<T> callback) { 
     callable_ = callable; 
     callback_ = callback; 
     activity=actvy; 
    } 

    @Override 
    protected T doInBackground(Void... ts) { 
     T result = null; 
     try{ 
      result = callable_.call(); 
     } catch (Exception e){ 
      Log.e(TAG, "Error invoking callable in AsyncTask callable: " + callable_, e); 
      error_ = e; 
     } 
     return result; 
    } 

    @Override 
    protected void onPostExecute(T r) { 
     if(error_ != null){ 
      callback_.error(error_); 
     } 
     else { 
      callback_.success(r,activity); 
     } 
    } 


    public static <V> void invoke(Callable<V> call, Fragment _frg, TaskCallback<V> callback) { 
     new CallableTask<V>(_frg,call, callback).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
    } 


// public CallableTask(android.support.v4.app.Fragment chatActivity,Callable<T> callable, TaskCallback<T> callback) { 
//  callable_ = callable; 
//  callback_ = callback; 
//  dynamicFragment=chatActivity; 
// } 
public CallableTask(android.support.v4.app.Fragment actvy,Callable<T> callable, TaskCallback<T> callback) { 
    callable_ = callable; 
    callback_ = callback; 
    dynamicFragment=actvy; 
} 

    public static <V> void invoke(Callable<V> call, android.support.v4.app.Fragment _frg, TaskCallback<V> callback) { 
     new CallableTask<V>(_frg,call, callback).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
    } 
} 

這被稱爲這裏...只有當點擊按鈕發送。

CallableTask.invoke(new Callable<Sent>() { 


      @Override 
      public Sent call() throws Exception { 
     }, this, new TaskCallback<Sent>() { 

      @Override 
      public void success(Sent result, Context context) { 
mGridArray.add(result); 
          if (mListAdapter != null) { 
           mListAdapter.notifyDataSetChanged(); 
           mListView.setSelection(mListAdapter.getCount()); 
           mListView.smoothScrollToPosition(mListAdapter.getCount()); 
} 
@Override 
      public void error(Exception e) { 
      } 
     }); 

感謝 Dhiren

+0

不是比AsyncTask長期運行的任務更好的選擇嗎? – nasch

+0

我正在閱讀有關服務,但我不明白我如何可以爲一個長期運行的任務接口服務,它將如何能夠填充UI?特別是當我離開那個UI ListView並移動到另一個。 – user2358826

+0

那麼如果ListView不再顯示在屏幕上,沒有什麼可更新的,對吧? – nasch

回答

0

我終於通過運行從發起的主題活動片段中的線程上Asynch.cancel電話解決了這個。當我離開活動。如果我沒有,它阻止任何其他任務運行,