工作線程(耗時操作)與UI線程實現異步更新
概述:工作線程A(多任務)執行期間,把單一任務的結果返回到UI線程更新。
實現: 創建基礎流程類(兩個handler)
public abstract class BaseQueueThread
{
/**
* 設置處理線程、ui處理流程,由子類實現
*/
protected abstract Object doInWork(int integer);//耗時操作
protected abstract void doInUi(Object obj);//更新ui
private Handler mWorkHandler,mUiHandler;
private boolean isDestroy;
private PriorityQueue<Message> mQueue;//優先隊列
public BaseQueueThread()
{
initProcess();
}
//暴露數據訪問接口
public void sendMessage(int priority,Integer obj)
{
Message msg = Message.obtain();
msg.what = priority;
msg.obj = obj;
mWorkHandler.sendMessage(msg);//從工作線程開始
}
private void initProcess()
{
mUiHandler = new Handler(Looper.getMainLooper());
HandlerThread handlerThread = new HandlerThread(getClass().getName());
handlerThread.start();
mWorkHandler = new Handler(handlerThread.getLooper())
{
private boolean isWait;//是否在等待ui更新
@Override
public void handleMessage(Message msg)
{
if(isDestroy)
{
return;
}
try
{
if(msg.what == -1)
{
if (mQueue == null)
{
isWait = false;
return;
}
msg = mQueue.poll();
if (msg == null)
{
isWait = false;
return;
}
}else if(isWait)
{
if (mQueue == null)
{
mQueue = new PriorityQueue<Message>(11, new Comparator<Message>()
{
@Override
public int compare(Message lhs, Message rhs)
{
return rhs.what - lhs.what;
}
});
}
Message message = Message.obtain();
message.copyFrom(msg);
mQueue.add(message);
return;
}else
{
isWait = true;
}
final Object result = doInWork((Integer) msg.obj);
mUiHandler.post(new Runnable()
{
@Override
public void run()
{
doInUi(result);
Message msg1 = Message.obtain();
msg1.what = -1;//通知ui更新成功
mWorkHandler.sendMessageAtFrontOfQueue(msg1);
}
});
} catch (Exception e)
{
isWait = false;
e.printStackTrace();
}
}
};
}
public void onDestroy()
{
isDestroy = true;
if(mWorkHandler!=null)
{
mWorkHandler.removeCallbacksAndMessages(null);
}
if (mUiHandler!=null)
{
mUiHandler.removeCallbacksAndMessages(null);
}
}
}
具體實現類:
public class EasyQueueThread extends BaseQueueThread
{
private TextView mTextView;
public EasyQueueThread(TextView textView)
{
super();
mTextView = textView;
}
@Override
protected Object doInWork(int obj)
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
return "ok"+obj;
}
@Override
protected void doInUi(Object obj)
{
mTextView.setText((String)obj);
}
}
發送工作線程消息,逐步更新UI:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView bt = (TextView) findViewById(R.id.button1);
EasyQueueThread easyQueueThread = new EasyQueueThread(bt);
for (int i = 0;i< 10 ;i++)
{
easyQueueThread.sendMessage(i,i);
}
}
}
3.總結:耗時操作不要放在UI線程,關鍵點要處理好什麼時候執行工作線程,什麼時候執行UI線程。
本文章轉載自:https://blog.csdn.net/yaonga/article/details/71216541