Skip to content

Instantly share code, notes, and snippets.

@minhngoc826
Forked from PhongHuynh93/0 background.java
Created May 10, 2024 10:46
Show Gist options
  • Save minhngoc826/21c18b596706fb66d4267e96259e0081 to your computer and use it in GitHub Desktop.
Save minhngoc826/21c18b596706fb66d4267e96259e0081 to your computer and use it in GitHub Desktop.
Worker thread, UI thread, Asynctask, Post, PostDelayed, RunOnUiThread
3 cách để làm task background:
1. asynctask: khi work on/off UI threads.
2. handler thread: thread api callbacks.
3. threadpool: chạy nhiều cv song song.
ta co asynctask method cho chạy song song asynctask.executeOnExecutor() nhưng cai này nhược thay vào đó ta chọn sd threadpool.
4. intentservice: ko dính gi tời UI threads.
###########################################################################################
background activity
1. khi ta đặt ta class chạy background trong activity thì implicit refer đến activity -> memory leaks xảy ra khi activity bị destroy asynctask vẫn hoan work.
https://www.youtube.com/watch?annotation_id=annotation_318323295&feature=iv&index=66&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&src_vid=qk5F6Bxqhr4&v=tBHPmQQNiS8
2. khi rotate activity, background thread lại update lên view nhưng ko còn tồn tại.
https://www.youtube.com/watch?annotation_id=annotation_3296249429&feature=iv&index=73&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&src_vid=qk5F6Bxqhr4&v=s4eAtMHU5gI
###########################################################################################
Systrace để check threads, cpu
https://developer.android.com/studio/profile/systrace.html?utm_campaign=app_series_systrace_021816&utm_source=gdev&utm_medium=yt-annt
để app ko lag thì phải 1s vẽ dc 60 frames -> 1 work phải làm xong trong > 16 ms , sd systrace để cpu dang làm j lâu.
###########################################################################################
worker thread die khi làm xong 1 task(works)
-> co cách nào làm worker ko die?
+ 1. loop (giu cho workerthread ko die, chạy lần lượt từng tasks trong ): nằm trong hàng đợi dang thực hiện.
+ 2. MessageQueue(đẩy works cho loop thực hiện): nằm trong hàng PendingTask (works đang đợi để thực hiện).
+ 3. 1 threads khác: đẩy works vào MessageQueue đê đợi.
https://www.youtube.com/watch?v=0Z5MZ0jL2BM&index=2&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
=> Cách hiện thực:
+ sd class Looper: chứa 1 2
+ sd class Handler: chua 3, nhưng ta thể đặt tạo đầu, cuối, giữa hàng đợi (ko phải lúc nào củng cuối).
=> Tổng 2 cái class trên ta 1 class chứa 2 HANDLERTHREAD
MessageQueue chứa các loại works sau: tùy vào cái làm work đó.
+ Intent
+ Runnable
+ Message
#####################################################################################
tại sao ko thể update view dc trên background thread?
Để tránh trường hợp 2 thread cùng access 1 vùng memory đồng thời sẽ gây crash -> nên android chỉ cho UI thread dc quyền access thôi.
#####################################################################################
từ worker thread reference đến 1 view cũng ko ổn nữa?
https://www.youtube.com/watch?v=tBHPmQQNiS8&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=3
do khi worker thread đang làm task activity bị destroy phải hủy view tạo view mới, trong khi worker thread đang refer sẽ làm việc trên view -> view lại refer đến toàn bọ activity (nếu ta đặt class async trong class activity ko static)-> ngăn activity bị gc xóa cho đén khi async làm xong.
Tệ hơn nữa khi rotate 3 lần thì sẽ 3 cái activity trong memory.
Trong TH trong 1 activity bị rotate, khi asynctask làm xong update lại view -> crash nếu view ko còn nữa. (hay nếu còn trong memory thì chỉ update lại view ).
=> KO DC REFER ĐẾN VIEW OBJECT NÀO TRONG THREAD BACKGROUND.
nhưng làm sao để update view từ background thread? => BẮT BUỘC TOP ACTIVITY HAY FRAGMENT PHẢI UPDATE VIEW.
bằng callback - interface.
#####################################################################################
DO NOT LEAK VIEWS
https://www.youtube.com/watch?annotation_id=annotation_309995137&feature=iv&index=23&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&src_vid=tBHPmQQNiS8&v=BkbHeFHn8JY
1. ko pass view cho asynctask, do async thực hien trong tương lai tương lai ta ko biết activity giữ view bị mất ko?
2. ko cho biến static access đến view
#####################################################################################
Khi nào sd background task asynctask ko thích hợp?
vd task quá dài như Camera.PreviewCallback sẽ nhận từng bức hình, mỗi bức 8MB nếu đẩy vao asynctask thì làm stall cac cv khác cung cần async (do async chỉ chạy dc 1 task) -> đẩy vao Handler thread, thread này chuyên xử thread dài nhận callback ko stall asynctask,
Muốn back lại UI thread khi xng ta sd runOnUiTHread()
https://developer.android.com/reference/android/hardware/Camera.PreviewCallback.html?utm_campaign=app_series_previewcallback_021816&utm_source=gdev&utm_medium=yt-annt
=> Handler thread tốt khi chạy task dài, ko UI, vd như task nén metrics trước khi up lên server.(thêm priority nữa).
#####################################################################################
Swimming in Threadpools.
https://www.youtube.com/watch?v=uCmHoEY1iTM&index=6&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
chạy nhiều tác vụ trên nhiều thread vd:
+ audio thread:
+ IO thread:
+ networking thread:
+ database thread:
=> ThreadPoolExcecutor: handle tất cả problem khi ta bật nhiều thread song song, vd cách balance giữa các thread đó. Tự động xóa thread khi idle....
=> Vấn : nên đặt ra bn threads? ko phải nhiều thread quá cũng tốt.
Ly do CPU la nhiều thread cùng chạy động thời, nếu như app ta nhiều thread thì cpu se bắt đợi dựa vào sự ưu tiện -> hóa ra lâu hơn ít thread thực hiện.
=> chỉ khi nào thread làm công việc lớn mới sử dung cái thread pools này.
https://developer.android.com/training/multiple-threads/index.html
#####################################################################################
Intent service
https://www.youtube.com/watch?v=9FweabuBi1U&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=7
1 cái lợi sd service chứ ko phải background làm xong thì mất-> vd app càn cập nhật trong 1 mốc nào đó thì đặt trong đây hay tạo 1 alarm cứ đến time nào đó thì kiu lên...
Nhược: stall các background khác như asynctask do ko chạy đồng thời asynctask với intentservice, sd broadcast receiver intent để giao tiếp với activity khi xong cái đó => do intent liên quan tới process communication (chtr quản global các process) cho nên perfrom châm hơn runOnUiThread (thread communication chtr quán local)
Ưu: activity service độ ưu tien cao hơn activity đang ẩn khi system phải kill ap -> ít dc kill hơn
=> cần phải xem asynctask làm dc ko mới đầy qua service.
#####################################################################################
The Importance of Thread Priority
Fun fact : Modern CPUs can only handle a certain number of threads at one time.
Once you get above that limit, they have to start scheduling which thread gets the next open block of CPU processing time.
And even better : This can influence the performance of your Android app.
https://www.youtube.com/watch?v=NwFXVsM15Co&index=9&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
# Chú ý: nếu sd AsyncTask thì ta khỏi cân gán do system đã gan cho class này rồi
#####################################################################################
view.post():
View#post will post the runnable on the queue (e.g. call the Handler#post)
Activity#runOnUiThread will call the run method directly
Another difference between Activity.runOnUiThread and view.post() is that the runnable in view.post() is called after the view is attached to a window.
http://stackoverflow.com/questions/10558208/android-whats-the-difference-between-activity-runonuithread-and-view-post
#####################################################################################
#####################################################################################
#####################################################################################
#####################################################################################
Is it possible to run multiple AsyncTask in same time?
http://stackoverflow.com/questions/18357641/is-it-possible-to-run-multiple-asynctask-in-same-time
http://android-er.blogspot.com/2014/04/run-multi-asynctask-as-same-time.html
http://stackoverflow.com/questions/24459145/how-to-run-multiple-background-tasks-in-parallel-using-asynctask-in-android
ko dc
By default, all of the AsyncTasks happen on a single thread. To use multiple threads, you need to use a different executor. AsyncTask has a thread pool executor you can use:
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
###########################################################################
Run Asynctask với Service đồng thời dc ko?
cũng ko dc
You can create your own Threads for this type of work. Since IntentService has its own queue same as AsyncTask you cannot run multiple background tasks at the same time.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
// Example 1: View.post(Runnable)
// For example, below is some code for a click listener that downloads an image from a separate thread and displays it in an ImageView:
// make a worker thread
Cách này sd interface Runnable method run class Thread trong java thuần để chạy background, sd post() để kéo lên UI thread -> ko tiện bằng asynctask
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
// access the UI thread from worker thread.
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
// change text every 7s, chạy tính từ mốc thời gian lúc đầu
@Override
protected void onResume() {
super.onResume();
for (int count = 0; count < arraylength; count++){
handler.postDelayed(new Runnable(){
@Override
public void run() {
mytexts.setText(myarray[count]);
}
}, 7000 * (count + 1));
}
}
// when click a button
//
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment