我有一个活动在服务器和客户端之间建立连接。 在这种情况下,当我单击“连接” (按钮)时,它将消息从客户端发送到服务器,一切都很好!
现在,请注意,所有这些都是在一项活动之间发生的。单个应用(单个android文件)可同时处理服务器和客户端的代码。
因此显然存在多线程。没问题。 所以,这是代码:
package com.nitishprajapati.tcpsocket;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.view.animation.Animation;
import android.view.animation.AlphaAnimation;
import java.io.DataInputStream;
import java.lang.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import android.os.Handler;
import java.net.Socket;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
EditText ip,data;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView myText = (TextView) findViewById(R.id.myText);
Animation anim = new AlphaAnimation(0.0f, 1.0f);
data = (EditText) findViewById(R.id.editText);
ip = (EditText) findViewById(R.id.ip);
anim.setDuration(150); //You can manage the time of the blink with this parameter
anim.setStartOffset(20);
anim.setRepeatMode(Animation.REVERSE);
anim.setRepeatCount(Animation.INFINITE);
myText.startAnimation(anim);
Thread myThread = new Thread(new MyServer());
myThread.start();
}
class MyServer implements Runnable{
ServerSocket ss;
Socket mySocket;
DataInputStream dis;
String message;
Handler handler = new Handler();
@Override
public void run(){
try{
ss = new ServerSocket(9700);
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),"Waiting for client: ",Toast.LENGTH_SHORT).show();
}
});
while(true){
mySocket = ss.accept();
dis = new DataInputStream(mySocket.getInputStream());
message = dis.readUTF();
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),"message received from client: "+message, Toast.LENGTH_SHORT).show();
}
});
}
}catch (IOException excep){
excep.printStackTrace();
}
}
}
public void button_click(View view){
BackgroundTask b = new BackgroundTask();
b.execute(ip.getText().toString(), data.getText().toString()); // all parameters should be of same type
// | ¯\_(o_o)_/¯ not sure
// |
// V
//Intent intent = new Intent(this, PaintActivity.class);
//startActivity(intent);
}
class BackgroundTask extends AsyncTask<String/*TypeOfVarArgParams, perhaps from execute()*/,Void,String/*Result*/>
{
Socket s;
DataOutputStream dos;
String ip, message;
@Override
protected String doInBackground(String... strings/*from execute method i guess*/) {
ip = strings[0]; // received from execute
message = strings[1]; // received from execute
try {
s = new Socket(ip, 9700);
dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(message);
dos.close();
}catch (IOException excep){
excep.printStackTrace();
}
return null;
}
}
}
Toast显然出现在其I.P.已给出。
那么,现在让我感到困惑的是:为什么我需要将客户代码放入AsyncTask<>
中?为什么不提供服务器代码?
为什么将服务器代码设为doInBackground()
,而不是服务器代码?
但是,我的主要问题是:
当我单击“连接”时,现在它应该在客户端和服务器上都打开一个新的活动“ PaintActivity
”,并且在客户端绘制时,我必须从客户端连续发送坐标。到服务器。因此,我将在哪里放置PaintActivity以及我该怎么做。背后的逻辑是什么?
这里是PaintActivity
:
package com.nitishprajapati.tcpsocket;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.Color;
public class PaintActivity extends Activity {
DrawingView dv ;
private Paint mPaint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Intent sendToLog =new Intent(getApplicationContext(),LoginActivity.class);
//startActivity(sendToLog);
dv = new DrawingView(this);
dv.setBackgroundColor(Color.parseColor("#000000"));
setContentView(dv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
}
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c; // Context
mPath = new Path(); // Path (mpath)
mBitmapPaint = new Paint(); // Paint
mBitmapPaint.setDither(false); // Dither
circlePaint = new Paint(); // Paint
circlePath = new Path(); // Path (circle)
circlePaint.setAntiAlias(true); // smoothening
circlePaint.setColor(Color.GREEN);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); // Bitmap
mCanvas = new Canvas(mBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
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) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
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;
}
}
}
那么,我该如何将两个部分链接在一起呢?