我遇到了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
不是比AsyncTask長期運行的任務更好的選擇嗎? – nasch
我正在閱讀有關服務,但我不明白我如何可以爲一個長期運行的任務接口服務,它將如何能夠填充UI?特別是當我離開那個UI ListView並移動到另一個。 – user2358826
那麼如果ListView不再顯示在屏幕上,沒有什麼可更新的,對吧? – nasch