Android实时绘制效果(一)
2)绘制部分
修改的ApiDemos的FingerPaint例子。有ClientView和ServerView,而父类BaseView放置共用的东西,也保证绘制效果一致。
2.1)BaseView.java
- public class BaseView extends View {
-
- protected OnExitedListener listener;
-
- public interface OnExitedListener {
- void onExited(View v);
- }
-
- protected Paint mPaint;
- protected Bitmap mBitmap;
- protected Canvas mCanvas;
- protected Path mPath;
- protected Paint mBitmapPaint;
-
- protected static final String KEY_INFO = "info";
- protected final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- String info = msg.getData().getString(KEY_INFO);
- Toast.makeText(getContext(), info, Toast.LENGTH_SHORT).show();
- }
- };
-
- public BaseView(Context context, int width, int height) {
- super(context);
-
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- mPaint.setDither(true);
- mPaint.setColor(0xFFFF0000);
- mPaint.setStyle(Paint.Style.STROKE);
- mPaint.setStrokeJoin(Paint.Join.ROUND);
- mPaint.setStrokeCap(Paint.Cap.ROUND);
- mPaint.setStrokeWidth(12);
-
- mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mCanvas = new Canvas(mBitmap);
- mPath = new Path();
- mBitmapPaint = new Paint(Paint.DITHER_FLAG);
-
-
- requestFocus();
- setFocusableInTouchMode(true);
- }
-
- protected void toastMessage(String info) {
- Message msg = mHandler.obtainMessage();
- Bundle data = new Bundle();
- data.putString(KEY_INFO, info);
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
- public void onBackPressed() {
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
- onBackPressed();
- }
- return super.onKeyDown(keyCode, event);
- }
-
- public void setOnExitedListener(OnExitedListener listener) {
- this.listener = listener;
- }
-
- }
2.2)ClientView.java
- public class ClientView extends BaseView implements OnClientListener {
-
- private EasyClient mEasyClient;
- private boolean hasStart = false;
- private Display mDisplay;
- private float wRatio = 1f, hRatio = 1f;
-
- private Runnable mRunnable = new Runnable() {
- @Override
- public void run() {
- Toast.makeText(getContext(), "已过5秒,网络不通畅?", Toast.LENGTH_LONG)
- .show();
- }
- };
-
- public ClientView(Context context, String host, int port, Display display) {
- super(context, display.getWidth(), display.getHeight());
- mDisplay = display;
-
- mEasyClient = new EasyClient(host, port, 10000);
- mEasyClient.setOnClientListener(this);
- mEasyClient.start();
-
- mHandler.postDelayed(mRunnable, 5000);
- }
-
- @Override
- public void onBackPressed() {
- mEasyClient.sendMessage(EasyServer.EXIT_COMMAND);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFAAAAAA);
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- canvas.drawPath(mPath, mPaint);
- }
-
- private float mX, mY;
-
- private void touch_start(float x, float y) {
- hasStart = true;
- mPath.reset();
- mPath.moveTo(x, y);
- mX = x;
- mY = y;
- }
-
- private void touch_move(float x, float y) {
- if (hasStart) {
- mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- } else {
- touch_start(x, y);
- }
- }
-
- private void touch_up(float x, float y) {
- hasStart = false;
-
- mPath.lineTo(x, y);
-
- mCanvas.drawPath(mPath, mPaint);
-
- mPath.reset();
- }
-
- @Override
- public void onConnectException() {
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接不到服务器!");
- if (null != listener) {
- listener.onExited(this);
- }
- }
-
- @Override
- public void onTimeoutException() {
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接服务器超时!");
- if (null != listener) {
- listener.onExited(this);
- }
- }
-
- @Override
- public void onSocketException() {
- mHandler.removeCallbacks(mRunnable);
- toastMessage("通信异常!");
- if (null != listener) {
- listener.onExited(this);
- }
- }
-
- @Override
- public void onConnected() {
- mHandler.removeCallbacks(mRunnable);
- toastMessage("连接上了服务器!");
- }
-
- @Override
- public void onReceive(String msg) {
- Object obj = JsonUtil.jsonToObj(msg);
- if (obj instanceof ScreenInfo) {
- ScreenInfo info = (ScreenInfo) obj;
- wRatio = ((float) mDisplay.getWidth()) / info.getWidth();
- hRatio = ((float) mDisplay.getHeight()) / info.getHeight();
- } else if (obj instanceof PonitInfo) {
- PonitInfo info = (PonitInfo) obj;
- float x = wRatio * info.getX();
- float y = hRatio * info.getY();
- switch (info.getState()) {
- case 0:
- touch_start(x, y);
- postInvalidate();
- break;
- case 1:
- touch_move(x, y);
- postInvalidate();
- break;
- case 2:
- touch_up(x, y);
- postInvalidate();
- break;
- }
- }
- }
-
- @Override
- public void onExited() {
- toastMessage("客户端退出了!");
- if (null != listener) {
- listener.onExited(this);
- }
- }
-
- }
2.3)ServerView.java
- public class ServerView extends BaseView implements OnServerListener {
-
- private EasyServer mEasyServer;
- private Display mDisplay;
-
- public ServerView(Context context, int port, Display display) {
- super(context, display.getWidth(), display.getHeight());
- mDisplay = display;
-
-
- mEasyServer = new EasyServer(port);
- mEasyServer.setOnServerListener(this);
- mEasyServer.start();
- }
-
- @Override
- public void onBackPressed() {
- mEasyServer.sendMessage(EasyServer.EXIT_COMMAND);
-
- if (null != listener) {
- listener.onExited(this);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- canvas.drawColor(0xFFAAAAAA);
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- canvas.drawPath(mPath, mPaint);
- }
-
- private float mX, mY;
- private static final float TOUCH_TOLERANCE = 4;
-
- private void touch_start(float x, float y) {
-
- mEasyServer.sendMessage(JsonUtil.objToJson(new PonitInfo(x, y, 0)));
-
- mPath.reset();
- mPath.moveTo(x, y);
- mX = x;
- mY = y;
- }
-
- private void touch_move(float x, float y) {
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
- if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
-
- mEasyServer.sendMessage(JsonUtil.objToJson(new PonitInfo(x, y, 1)));
-
- mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- }
- }
-
- private void touch_up() {
-
- mEasyServer.sendMessage(JsonUtil.objToJson(new PonitInfo(mX, mY, 2)));
-
- mPath.lineTo(mX, mY);
-
- mCanvas.drawPath(mPath, mPaint);
-
- mPath.reset();
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- touch_start(x, y);
- invalidate();
- break;
- case MotionEvent.ACTION_MOVE:
- touch_move(x, y);
- invalidate();
- break;
- case MotionEvent.ACTION_UP:
- touch_up();
- invalidate();
- break;
- }
- return true;
- }
-
- @Override
- public void onBindException() {
- toastMessage("端口占用了,请关闭应用后重开!");
- }
-
- @Override
- public void onSocketException(InetAddress ip) {
- toastMessage(ip + "异常退出!");
- }
-
- @Override
- public void onClientConnected(InetAddress ip) {
- toastMessage(ip + "建立了连接!");
-
- mEasyServer.sendMessage(JsonUtil.objToJson(new ScreenInfo(mDisplay
- .getWidth(), mDisplay.getHeight())));
- }
-
- @Override
- public void onReceive(InetAddress ip, String msg) {
-
- }
-
- @Override
- public void onExited(InetAddress ip) {
- toastMessage(ip + "正常退出!");
- }
-
- }
四、后记
1、NIO Socket通信还不是很熟悉,所以还是Socket了。至于多线程和NIO效率在各情况下孰优孰劣不清楚。而长连接是为了实时。
2、客户端连接以Socket集合来记录,在n多时会有什么什么。算了,现Demo不面临这种风险~
3、现在的通信消息太复杂了,没必要这样的。
可以多拿几个设备测试玩玩^^