您的位置:首页 > 移动开发 > Android开发

【Android 并发编程】线程间通信的三种基本方式,android线程

2016-10-15 22:37 711 查看
1. 使用管道流Pipes

“管道”是java.io包的一部分。它是Java的特性,而不是Android特有的。一条“管道”为两个线程建立一个单向的通道。生产者负责写数据,消费者负责读取数据。

下面是一个使用管道流进行通信的例子。

public class PipeExampleActivity extends Activity {

private static final String TAG = "PipeExampleActivity";
private EditText editText;

PipedReader r;
PipedWriter w;

private Thread workerThread;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

r = new PipedReader();
w = new PipedWriter();

try {
w.connect(r);
} catch (IOException e) {
e.printStackTrace();
}

setContentView(R.layout.activity_pipe);
editText = (EditText) findViewById(R.id.edit_text);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}

@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
try {
if(count > before) {
w.write(charSequence.subSequence(before, count).toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void afterTextChanged(Editable editable) {
}
});

workerThread = new Thread(new TextHandlerTask(r));
workerThread.start();
}

@Override
protected void onDestroy() {
super.onDestroy();
workerThread.interrupt();
try {
r.close();
w.close();
} catch (IOException e) {
}
}

private static class TextHandlerTask implements Runnable {
private final PipedReader reader;

public TextHandlerTask(PipedReader reader){
this.reader = reader;
}
@Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
try {
int i;
while((i = reader.read()) != -1){
char c = (char) i;

Log.d(TAG, "char = " + c);
}

} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}


在这个例子中,对EditText设置一个TextWatcher监听,一旦EditText的内容发生改变,就向“管道”中输入字符,它就是所谓的生产者。同时,有一个工作线程负责从管道中读取字符,它就是所谓的消费者。这样,就实现了UI线程和工作线程之间的数据通信。

2. 共享内存

多个线程共享同一份内存,就是说,一个变量可以同时被多个线程所访问。这里要特别注意同步和原子操作的问题。

Java中最基本的同步例子。

synchronized(this) {
while(isConditionFullfilled == false) {
wait();
}

notify();
}

如果觉得使用wait/notify比较麻烦,可以使用Java提供的BlockingQueue,从名字就可以看出它是一个阻塞队列。看下面的例子。

public class ConsumerProducer {
private final int LIMIT = 10;
private BlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<Integer>(LIMIT);

public void produce() throws InterruptedException {
int value = 0;
while (true) {
blockingQueue.put(value++);
}
}

public void consume() throws InterruptedException {
while (true) {
int value = blockingQueue.take();
}
}

}


3. 使用Hander和Message

Handler的机制网上有很多教程,对其不太清楚的同学可以Google一下。

我做一下简略的总结。

一个线程对应一个Looper,一个Looper持有一个MessageQueue,一个Looper可以与多个Handler绑定,一个MessageQueue中可以包含多个Message。

下面是一个使用Handler的例子。

public class HandlerExampleActivity extends Activity {

private final static int SHOW_PROGRESS_BAR = 1;
private final static int HIDE_PROGRESS_BAR = 0;
private BackgroundThread mBackgroundThread;

private TextView mText;
private Button mButton;
private ProgressBar mProgressBar;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_example);

mBackgroundThread = new BackgroundThread();
mBackgroundThread.start();

mText = (TextView) findViewById(R.id.text);
mProgressBar = (ProgressBar) findViewById(R.id.progress);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mBackgroundThread.doWork();
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
mBackgroundThread.exit();
}

private final Handler mUiHandler = new Handler() {
public void handleMessage(Message msg) {

switch(msg.what) {
case SHOW_PROGRESS_BAR:
mProgressBar.setVisibility(View.VISIBLE);
break;
case HIDE_PROGRESS_BAR:
mText.setText(String.valueOf(msg.arg1));
mProgressBar.setVisibility(View.INVISIBLE);
break;
}
}
};

private class BackgroundThread extends Thread {

private Handler mBackgroundHandler;

public void run() {
Looper.prepare();
mBackgroundHandler = new Handler();
Looper.loop();
}

public void doWork() {
mBackgroundHandler.post(new Runnable() {
@Override
public void run() {
Message uiMsg = mUiHandler.obtainMessage(SHOW_PROGRESS_BAR, 0,
0, null);
mUiHandler.sendMessage(uiMsg);

Random r = new Random();
int randomInt = r.nextInt(5000);
SystemClock.sleep(randomInt);

uiMsg = mUiHandler.obtainMessage(HIDE_PROGRESS_BAR, randomInt,
0, null);
mUiHandler.sendMessage(uiMsg);
}
});
}

public void exit() {
mBackgroundHandler.getLooper().quit();
}
}
}


救命 android线程间通信 handler message之类的

线程间通讯(三种方式)::

public class AnrActivity extends Activity implements OnClickListener {

TextView text;

Handler handler;

ProgressBar bar;

private class MyAsycnTask extends AsyncTask<URL, Integer, String>{

@Override

protected void onProgressUpdate(Integer... values) {

bar.setProgress(values[0]);

text.setText("进度:"+values[0]+"%");

super.onProgressUpdate(values);

}

@Override

protected String doInBackground(URL... params) {

for (int i = 0; i <100; i++) {

try {

publishProgress(i+1);

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

return "success";

}

@Override

protected void onPostExecute(String result) {

text.setText(result);

}

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Button down = (Button) this.findViewById(R.id.button1);

Button receiver = (Button) this.findViewById(R.id.button2);

Button update = (Button)this.findViewById(R.id.button3);

bar = (ProgressBar)this.findViewById(R.id.progressBar1);

text = (TextView)this.findViewById(R.id.text);

update.setOnClickListener(this);

down.setOnClickListener(this);

receiver.setOnClickListener(this);

}

@Override

public void onClick(final View v) {

switch (v.getId()) {

case R.id.button1:

//通过 Asycntask 进行通讯

MyAsycnTask myAsycnTask = new MyAsycnTask();

myAsycnT......余下全文>>

 

面试被问到android中两个子线程怎通信,我懵了

构造HandlerThread类的对象mHandlerThread,这样生成一个子线程可以调用new MyHandler(mHandlerThread.getLooper())来获取子线程的handler,另一个子线程发消息,收到消息的就是子线程而不是主线程了。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: