Android 다 중 스 레 드 처리 의 다 중 스 레 드 상세 설명
19145 단어 Android다 중 스 레 드 처리
1.이렇게 하면 ui 를 조작 할 수 있 지만 run 은 메 인 스 레 드 에 있 습 니 다.인쇄 된 Log 스 레 드 이름 이 main 인 것 을 보면 메 인 스 레 드 임 을 설명 합 니 다.
이것 이 바로 run 방법 에서 ui 를 직접 조작 할 수 있 는 이유 입 니 다.왜냐하면 그것 은 본질 적 으로 ui 스 레 드 이기 때 문 입 니 다.
handler.post(new Runnable(){
public void run(){
Log.e(" :",Thread.currrentThread.getName());// de main
setTitle(" ");
}
});
2.HandlerThread 를 통 해 looper 를 얻 을 수 있 지만 이 run 방법 에서 ui 를 조작 하 는 것 은 불가능 합 니 다.그러나 이것 은 분명 단점 이 있 습 니 다.만약 에 post(r)방법 을 여러 번 실행 하면 사실은 HandlerThread 스 레 드 를 가 는 것 입 니 다.만약 네가 다섯 번,n 번 을 실행한다 면,사실은 한 번 이 고,그것들 은 직렬 이다.만약 5 장의 그림 을 다운로드 한다 면,당신 은 그림 이 첫 번 째 장 을 다 내 려 야만 두 번 째 장 을 내 려 갈 수 있 습 니 다.주 스 레 드 looper 가 있 는 handler 만 ui 를 조작 할 수 있 고,주 스 레 드 ui 는 handler 의 handlerMessage()방법 에서 Ui 를 조작 할 수 있 으 며,handler 의 post(r)run 방법 에서 Ui 를 조작 할 수 있 음 을 증명 합 니 다.
HandlerThread ht = new HandlerThread("handler thread");
ht.start();
handler = new Handler(ht.getLooper());
handler.post(new Runnable(){// run() ht.start()
public void run(){
Log.e(" :",Thread.currrentThread.getName());// handler thread
setTitle(" ");//
//android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
}
});
이렇게 하면 어떻게 해 야 합 니까?하하,handler 를 구축 하 는 데 참여 하지 않 아 도 됩 니 다.이 handler 로 메 시 지 를 보 내 고 처리 하 며 위의 handler 로 새 스 레 드 를 엽 니 다.
mainHandler = new Handler(){
protecket void handlerMessage(Message msg){
setTitle(" ");//
}
}
handler.post(new Runnable(){// run() ht.start()
public void run(){
Log.e(" :",Thread.currrentThread.getName());// handler thread
mainHandler.sendEmpetMessage();// mainHandler
//setTitle(" ");//
//android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
}
});
로그 인쇄:3.사실 두 번 째 방법 은 번 거 롭 고 비효 율 적 입 니 다.하 나 는 스 레 드 를 시작 하고 하 나 는 메 시 지 를 처리 하 는 데 사 용 됩 니 다.스 레 드 를 시작 하 는 handler 는 looper 가 있어 야 하기 때문에 HanderThread 를 예화 해 야 합 니 다.메 시 지 를 처리 하 는 handler 는 looper 가 필요 하지 않 습 니 다.기본 스 레 드 가 있 는 looper 이기 때문에 이 handler 에서 ui 를 처리 할 수 있 습 니 다.
사실은 하나의 handler 만 예화 하고 메 인 스 레 드 에 인삼 이 없 는 handler 를 구축 한 다음 에 메 시 지 를 보 내 고 처리 할 수 있 습 니 다.스 레 드 를 만 드 는 작업 은 handler 를 사용 하지 않 고 new Thread(r).start()를 사용 합 니 다.그리고 r 의 run()방법 에서 논리 적 인 사 무 를 처리 합 니 다.
이런 모드 로 5 장의 그림 을 다운로드 하면 한 장 한 장 씩 보 여 주 는 그림 을 보지 못 할 수도 있 고,두 번 째 사진 이 먼저 나 올 수도 있 고,동시에 3 장 이 나 올 수도 있 으 며,5 개의 라인 이 무 작위 로 나 올 수도 있다.
private void loadImagesByThread(final String url,final int id){// Thread new
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
Drawable drawable = null;
try {
drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = mainHandler.obtainMessage();
msg.what = 2012;
msg.arg1 = id;
msg.obj = drawable;
msg.sendToTarget();
}
}).start();
}
로그 인쇄:4.AsyncTask
비동기 작업 으로 다 중 작업 모델 을 구성 하 는 것 도 그리 건장 하지 않 으 므 로 여러 개의 AsyncTask 인 스 턴 스 를 만들어 야 합 니 다.하나의 AsyncTask 는 한 번 만 실행 할 수 있 으 며,패스트푸드 류 의 스 레 드 를 한 번 에 다 사용 할 수 없습니다.
AsyncTask 하위 클래스 를 실현 하 는 가장 중요 한 두 가지 방법 중 하 나 는 doInBackground(params)입 니 다.하 나 는 onPost Execute(result)입 니 다.doInBackground()방법 에서 시간 소모 업 무 를 처리 하고 결 과 를 되 돌려 줍 니 다.되 돌아 오 는 값 은 onPost Execute 방법 을 매개 변수 로 한 다음 onPost Execute()에서 결 과 를 ui 에 보 여 줍 니 다.
단계:
① 사례 화 AsyncTask:
AsyncTask 를 실례 화하 고 task.exec(pamas)를 통과 합 니 다.매개 변 수 를 전달 합 니 다.이 매개 변수 목록 은 동적 입 니 다.하나 일 수도 있 고 여러 개 일 수도 있 으 며 길 이 를 가 변 할 수 있 습 니 다.
AsyncTask
② onPreExecute 방법:
이 방법 은 인자 도 없고 반환 값 도 없 으 니 이 방법 에서 알림 을 할 수 있 습 니 다.예 를 들 어 show 하나의 Dialog 나 Toast 를 쳐 서 사용자 에 게 다운로드 하기 시작 했다 고 알려 줍 니 다.
③ doInBackground(params)방법:
AsyncTask 내부 구조 에 들 어가 면 먼저 reslut doInBackground(params)방법 을 실행 합 니 다.이 방법 은 시간 이 걸 리 는 사 무 를 처리 합 니 다.exec()의 매개 변 수 는 이 방법 에 매개 변 수 를 전달 하고 반환 값 은 onPostExecute()의 매개 변수 가 됩 니 다.진 도 를 업데이트 하려 면 publicProgress()방법 을 실행 해 야 합 니 다.
④ onProgressUpdate(values)방법:
이 방법의 매개 변 수 는 doInBackground()방법 에서 publicProgress()방법 을 실행 해 야 합 니 다.이 방법 은 매개 변 수 를 onProgressUpdate()방법 에 전달 한 다음 에 이 방법 에서 ui 의 업데이트 전 시 를 할 수 있 습 니 다.예 를 들 어 진도 항목 의 값 은 이 values 값 을 통 해 동태 적 으로 변 할 수 있 습 니 다.
⑤ onPost Execute(result)방법:
여기 가 바로 업무 처리 가 끝 난 방법 입 니 다.doInBackground 방법 이 실 행 된 결 과 는 여기에 전 달 됩 니 다.만약 이 방법 이 데 이 터 를 되 돌려 준다 면.이 방법 에서 Ui 를 처리 할 수 있 고 처 리 된 데 이 터 를 ui 에 보 여줄 수 있 습 니 다.예 를 들 어 그림,문자,네가 원 하 는 모든 결과.
private void loadImageByAsyncTask(final String url,final int id){// , handler
DownloadTask task = new DownloadTask();
task.execute(""+id,url);//AsyncTask
}
class DownloadTask extends AsyncTask<String,Integer,Drawable>{
int id;
@Override
protected Drawable doInBackground(String... params) {//params url id
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
Drawable drawable = null;
this.id = Integer.parseInt(params[0]);
try {
drawable = Drawable.createFromStream(new URL(params[1]).openStream(), "image.gif");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return drawable;
}
@Override
protected void onPostExecute(Drawable result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
}
여기 인쇄 된 log5.ExecutorServie 스 레 드 탱크
Executors 의 정적 방법 으로 만 듭 니 다.보통 세 가지 가 있 습 니 다.
1.단일 스 레 드:Executors.newSingleThreadExecutor();
2.고정 수량 스 레 드:Executors.newFixedThreadPool();
3.동적 스 레 드:Executors.newCachedThreadPool();
여기 서 저 희 는 고정 5 개의 스 레 드 로 응용 합 니 다.사용 방법 은 ExecutorService 대상 을 만 든 다음 submit(r)를 실행 하면 Runnable 대상 을 시작 할 수 있 습 니 다.스 레 드 탱크 로 관리 하 는 장점 은 시스템 의 안정 적 인 운행 을 확보 하고 대량의 스 레 드,높 은 작업량 의 상황 에서 사용 할 수 있다 는 것 이다.만약 에 1000 장의 그림 을 보 여 주 려 면 1000 개의 스 레 드 를 만들어 서 불 러 오 면 시스템 이 죽 을 것 이다.스 레 드 탱크 를 사용 하면 이 문 제 를 피 할 수 있 습 니 다.5 개의 스 레 드 로 돌아 가면 서 실행 할 수 있 습 니 다.5 개의 한 조 가 실 행 된 스 레 드 는 직접 회수 하지 않 고 다음 에 실 행 될 때 까지 기다 릴 수 있 습 니 다.그러면 시스템 에 대한 비용 을 많이 줄 일 수 있 습 니 다.
private void loadImagesByExecutors(final String url,final int id){
service.submit(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
try {
final Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
mainHandler.post(new Runnable(){
@Override
public void run() {//
// TODO Auto-generated method stub
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
Log:사실 분명히 말 하지 못 했 을 수도 있 습 니 다.첫 번 째 는 다 중 스 레 드 가 아 닙 니 다.
1.loadImages ByHandler()는 Handler.post()방법 을 통 해 두 개의 Handler 를 구축 하여 통신 한다.
2.loadImages ByThread(),이것 은 직접 new Thread()에서 스 레 드 를 시작 합 니 다.메 인 스 레 드 의 handler 에서 메 시 지 를 처리 합 니 다.
3.loadImage ByAsyncTask(),이 작업 은 비동기 작업 을 사용 합 니 다.모든 것 이 내부 구조 에서 이 루어 지고 안에서 Ui 를 조작 할 수 있 습 니 다.
4.loadImages ByExecutors()는 스 레 드 탱크 를 사용 하여 스 레 드 를 제어 할 수 있 고 안정 적 인 운행 을 보장 합 니 다.
사실 자주 사용 하 는 것 은 바로 뒤의 세 가지 이다.두 번 째 용법 은 유연 하고 간단 하지만 대량의 임무 에 적합 하지 않다.세 번 째 는 일반적으로 하나의 임무,일회 성 임무 에 적용 된다.네 번 째 는 보통 대량의 고밀도 로 실 행 된 사용 상황,예 를 들 어 그림 을 대량으로 불 러 오고 파일 을 대량으로 다운로드 하 는 등 이다.
그림 을 보 세 요.
모든 원본 코드:
package com.bvin.exec;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
private Handler handler ;
private Button bt;
private Handler mainHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if(msg.what == 2012){
// ui
((ImageView)MainActivity.this.findViewById(msg.arg1)).setImageDrawable((Drawable)msg.obj);
}
}
};
private ExecutorService service = Executors.newFixedThreadPool(5);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initViews();
HandlerThread ht = new HandlerThread("down image thread");
ht.start();
handler = new Handler(ht.getLooper()){// looper handler ui
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
}
};
}
private void initViews(){
bt = (Button)findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/23c1625aca99f02c50d8e510383a34e7.jpg",R.id.iv1);
loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/c4698d97ef6d10722c8e917733c7beb3.jpg",R.id.iv2);
loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/f332ffe433be2a3112be15f78bff5a40.jpg",R.id.iv3);
loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/6ff8a9c647a1e80bc602eeda48865d4c.jpg",R.id.iv4);
loadImagesByExecutors("http://news.baidu.com/z/resource/r/image/2012-11-23/f104d069f7443dca52a878d779392874.jpg",R.id.iv5);
}
});
}
private void loadImagesByHandler(final String url,final int id){// looper handler.post(runnable),
handler.post(new Runnable(){// handler Looper
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
Drawable drawable = null;
try {
drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//SystemClock.sleep(2000);
//((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
Message msg = mainHandler.obtainMessage();
msg.what = 2012;
msg.arg1 = id;
msg.obj = drawable;
msg.sendToTarget();
}
});
}
private void loadImagesByThread(final String url,final int id){// Thread new
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
Drawable drawable = null;
try {
drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg = mainHandler.obtainMessage();
msg.what = 2012;
msg.arg1 = id;
msg.obj = drawable;
msg.sendToTarget();
}
}).start();
}
private void loadImageByAsyncTask(final String url,final int id){// , handler
DownloadTask task = new DownloadTask();
task.execute(""+id,url);//AsyncTask
}
private void loadImagesByExecutors(final String url,final int id){
service.submit(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
try {
final Drawable drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
mainHandler.post(new Runnable(){
@Override
public void run() {//
// TODO Auto-generated method stub
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class DownloadTask extends AsyncTask<String,Integer,Drawable>{
int id;
@Override
protected Drawable doInBackground(String... params) {//params url id
// TODO Auto-generated method stub
Log.e(" :", ""+Thread.currentThread().getName());
Drawable drawable = null;
this.id = Integer.parseInt(params[0]);
try {
drawable = Drawable.createFromStream(new URL(params[1]).openStream(), "image.gif");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return drawable;
}
@Override
protected void onPostExecute(Drawable result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
}
}
이상 은 안 드 로 이 드 다 중 스 레 드 에 대한 자료 정리 입 니 다.추 후 관련 지식 을 계속 보충 하 겠 습 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.