最近准备面试,在此记录一下学到的东西。
安卓这边线程通信的话,通常情况下我用到的就是handler和广播,基本所有问题都能解决了。今天去面试,面试官问到了这个问题,结果他说这两种方式的效率太低,他们使用的是管道流,emmmmmm,表示一脸懵逼。
回来查了一下,自己试了试,感觉还可以吧,在此记录一下。
Activity代码:
/**
* 使用管道流进行线程之间的通信
*/
public class PipedActivity extends AppCompatActivity {
Product Product;//生产线程
Consumer Consumer;//消费线程
PipedInputStream pipedInputStream;
PipedOutputStream pipedOutputStream;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thread);
pipedOutputStream = new PipedOutputStream();
pipedInputStream = new PipedInputStream();
Product = new Product(pipedOutputStream, new User("张三 ", "123456"));//发送线程
Consumer = new Consumer(pipedInputStream);//接受线程
try {
pipedOutputStream.connect(pipedInputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.click:
Product.start();
Consumer.start();
break;
default:
break;
}
}
/**
* 生产线程
*/
public class Product extends Thread {
private PipedOutputStream outputStream;
private User user;
public Product(PipedOutputStream outputStream, User user) {
this.outputStream = outputStream;
this.user = user;
}
@Override
public void run() {
try {
outputStream.write(StreamUtil.object2ByteArray(user));
outputStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public class Consumer extends Thread {
private PipedInputStream inputStream;
public Consumer(PipedInputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
try {
final byte[] bytes = new byte[1024];
inputStream.read(bytes);
inputStream.close();
final User user = (User) StreamUtil.byteArray2Object(bytes);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(PipedActivity.this, "消费者线程接收到数据" + user.getName(), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Util代码:
**
* zhd Streamutil类
*/
public class StreamUtil {
/**
* 将对象转换为byte数组
*
* @param objtct 输入对象
* @return
* @throws IOException
*/
public static byte[] object2ByteArray(Object objtct) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = null;
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(objtct);
byte[] bytes = byteArrayOutputStream.toByteArray();
return bytes;
}
/**
* 将byte转换为Object
*
* @param bytes
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object byteArray2Object(byte[] bytes) throws IOException, ClassNotFoundException {
ObjectInputStream sIn = null;
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
sIn = new ObjectInputStream(in);
return sIn.readObject();
}
/**
* 将流转换为String
*
* @param is
* @return
*/
public static String getStringFromInputStream(InputStream is) {
String result = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = -1;
byte buffer[] = new byte[1024];
while ((len = is.read(buffer)) != -1) {
out.write(buffer, 0, buffer.length);
}
result = new String(out.toByteArray());
is.close();
out.close();
} catch (Exception e) {
}
return result;
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PipedActivity">
<Button
android:id="@+id/click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="发送数据" />
</android.support.constraint.ConstraintLayout>
代码就这些,这部分的话,看不到管道流和handler和广播的效率差距在哪,希望大神给解释一下。
不知道你们要不要源码地址,先放上
https://github.com/zhddream/AndroidPiped