一、由于在做“多屏互动”,在试各种解决方案;
二、这个方法的大概思路为:
1、基于C/S模式,建立socket连接;
2、服务器端,启动线程,不断截屏,并把图像流信息写到DataOutPutStream中;
3、客户端,不停读DataInPutStream,然后BitmapFactory.decodeByteArray,创建Bitmap,通知Handler更新试图;
三、缺点:截屏,信息流的读写过程很耗时。
四、源码
1、服务器端源码(PC)
Server.java:
public class Server {
/**
* 写一个服务器打开的程序
* @param port:端口
*/
public void startServer (int port){
try{
//建立一个Serverc 对象
java.net.ServerSocket sc=new java.net.ServerSocket(port);
System.out.println("服务器创建成功");
//开始不断地接收数据
while (true){
//建立一个联结对象
java.net.Socket client=sc.accept();
UserThread ust=new UserThread(client);
ust.init();
ust.start();
}
}catch(Exception ef){
ef.printStackTrace();
}
}
public static void main(String args[]){
Server cr=new Server();
cr.startServer(9090);
}
}
UserThread.java:
public class UserThread extends Thread {
// 定义构造器,传入对client
private java.net.Socket client;
private java.io.InputStream ins;
private java.io.OutputStream ous;
public UserThread(java.net.Socket client) {
this.client = client;
}
// 初始化
public void init() {
try {
ins = client.getInputStream();
ous = client.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 写run方法
public void run() {
try {
sendImg();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendImg() throws Exception {
DataOutputStream dous = new DataOutputStream(ous);
Robot ro = new Robot();
Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle r = new Rectangle(scrSize.width, scrSize.height);
System.out.println("大小是:" + scrSize.height + " " + scrSize.width);
while (true) {
BufferedImage bui = ro.createScreenCapture(r);
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
boolean resultWrite = ImageIO.write(bui, "jpg", imageStream);
byte[] tagInfo = imageStream.toByteArray();
// System.out.println(tagInfo.length);
// System.out.println(tagInfo[0] + " " + tagInfo[1]);
// Image img = Toolkit.getDefaultToolkit().createImage(tagInfo, 0,
// tagInfo.length);
dous.writeInt(tagInfo.length + 5);
dous.writeByte((byte) 4);
dous.write(tagInfo);
// Thread.sleep(100);
}
}
}
2、客户端(Android)
DeskShowActivity.java:
public class DeskShowActivity extends Activity{
//定义各个stream
private java.io.InputStream ins;
private java.io.OutputStream ous;
private java.io.DataInputStream dins;
//定义各个组件
private ImageView img;
private TextView tvw;
//定义一个Bitmap 用来存ImageView的每个图
private Bitmap bmm;
//放接收到数据的数组
private byte[] data;
//初始化
public void init(String ip){
try{
System.out.println(ip);
java.net.Socket soc=new java.net.Socket(ip,9090);
ins=soc.getInputStream();
dins=new DataInputStream(ins);
ous=soc.getOutputStream();
System.out.println("创建成功!");
}catch(Exception ef){
ef.printStackTrace();
}
}
//内部类,myHandler
class MyHandler extends Handler{
public MyHandler(){
}
public MyHandler(Looper looper){
super(looper);
}
public void handleMessage(Message msg){
img.setImageBitmap((Bitmap)msg.obj);
}
}
//onCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainfunctionactivity);
//得到各个组件
img=(ImageView)findViewById(R.id.imgView);
// tvw=(TextView)findViewById(R.id.exitTextView);
//
// //textView 添加监听器
// tvw.setOnClickListener(new OnClickListener(){
// public void onClick(View v) {
// System.exit(0);
// }
// });
init("192.168.1.179");
Looper looper = Looper.myLooper();
//此处甚至可以不需要设置Looper,因为 Handler默认就使用当前线程的Looper
final MyHandler myhandler= new MyHandler(looper);
new Thread() {
public void run() {
while(true){
try{
data=new byte[dins.readInt()-5];
dins.readByte();
//注意,这里要用readfully
dins.readFully(data);
//注意,这里要回收bmm ,否则报错
if (bmm!=null){
bmm.recycle();
}
bmm=BitmapFactory.decodeByteArray(data, 0, data.length);
System.out.println("decode after:"+System.currentTimeMillis());
//每一百ms 执行 (可调)
// Thread.sleep(100);
//创建一个Message对象,并把得到的天气信息赋值给Message对象
Message message = Message.obtain();
message.obj = (Bitmap)bmm;
myhandler.sendMessage(message);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
}
五、运行效果: