Android实现中国象棋游戏(局域网版)

本文实例为大家分享了Android实现中国象棋游戏的具体代码,供大家参考,具体内容如下
实现环境:android studio 3.2.1, 手机分辨率为: 1920 * 1080
局域网 UDP 连接
分主活动类,棋类,主机类
代码如下:
清单文件要添加的权限:


主活动:
package chinachess; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; public class MainActivity extends AppCompatActivity implements View.OnClickListener {private TextView tvMyIp; private EditText editIp; private EditText editReceiverPort; private EditText editSendrPort; private Button btnConn; private TextView tvTitle; private TextView tvTitle2; private TextView tvTitle3; @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); }private void initView() {tvMyIp = (TextView) findViewById(R.id.tvMyIp); editIp = (EditText) findViewById(R.id.editIp); editReceiverPort = (EditText) findViewById(R.id.editReceiverPort); editSendrPort = (EditText) findViewById(R.id.editSendrPort); btnConn = (Button) findViewById(R.id.btnConn); btnConn.setOnClickListener(this); tvTitle = (TextView) findViewById(R.id.tvTitle); tvTitle2 = (TextView) findViewById(R.id.tvTitle2); tvTitle3 = (TextView) findViewById(R.id.tvTitle3); getIp(); }// 将用于连接的控件隐藏掉public void uiGone() {tvMyIp.setVisibility(View.GONE); editIp.setVisibility(View.GONE); editReceiverPort.setVisibility(View.GONE); editSendrPort.setVisibility(View.GONE); btnConn.setVisibility(View.GONE); btnConn.setVisibility(View.GONE); tvTitle.setVisibility(View.GONE); tvTitle2.setVisibility(View.GONE); tvTitle3.setVisibility(View.GONE); }// 获取局域网 ip 的方法private void getIp() {String s; try {for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {NetworkInterface face = en.nextElement(); for (Enumeration enAddr = face.getInetAddresses(); enAddr.hasMoreElements(); ){InetAddress addr = enAddr.nextElement(); if (!addr.isLoopbackAddress()) {s = addr.getHostAddress(); // 只获取区域网 ip 地址if ("192".equals(s.substring(0, 3))) {tvMyIp.setText("IP: " + s); }}}}} catch (SocketException e) {e.printStackTrace(); }}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnConn:submit(); break; }}private void submit() {// validateString ip = editIp.getText().toString().trim(); if (TextUtils.isEmpty(ip)) {Toast.makeText(this, "IP不可为空!", Toast.LENGTH_SHORT).show(); return; }String receiverPort = editReceiverPort.getText().toString().trim(); if (TextUtils.isEmpty(receiverPort)) {Toast.makeText(this, "接收端口不可为空!", Toast.LENGTH_SHORT).show(); return; }String sendPort = editSendrPort.getText().toString().trim(); if (TextUtils.isEmpty(sendPort)) {Toast.makeText(this, "发送端口不可为空!", Toast.LENGTH_SHORT).show(); return; }// TODO validate success, do something// 开启服务器或客户端,并添加到主活动中ServerView server = new ServerView(this, Integer.valueOf(receiverPort), Integer.valueOf(sendPort), ip); ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); addContentView(server, params); server.startServer(); }}

布局:
Android实现中国象棋游戏(局域网版)
文章图片


【Android实现中国象棋游戏(局域网版)】btn_blue.xml:

棋类:
package chinachess; public class Chess {// 标记当前棋的颜色是红棋还是黑棋public static final int BLACK = 1; public static final int RED = 2; // 存储当前棋子是红棋还是黑棋private int player; // 当前棋子的名字private String name; // 图片 idprivate int imageId; // 图片编号// 0-15 红色,16-31 黑色// 0-帅// 1,2-士// 3,4-相// 5,6-马// 7,8-车// 9,10-炮// 11-15-卒// 16-黑帅// ...private int num; // 当前棋在棋盘中的位置,posX 为行,posY 为列private int posX, posY; public Chess(int player, String name, int num) {this.player = player; this.name = name; this.num = num; // 红旗的图片 idint[] redId = {R.drawable.shuai, R.drawable.shi, R.drawable.xiang, R.drawable.ma, R.drawable.che,R.drawable.pao, R.drawable.bing}; // 黑旗的图片 idint[] blackId = {R.drawable.shuai1, R.drawable.shi1, R.drawable.xiang1, R.drawable.ma1, R.drawable.che1,R.drawable.pao1, R.drawable.bing1}; // 所有的棋的种类String[] names = {"帅", "士", "相", "马", "车", "炮", "卒"}; // 根据当前棋的颜色来匹配不同的图片if (player == RED) {for (int i = 0; i < names.length; i++) {if (names[i].equals(name)) {imageId = redId[i]; break; }}} else {for (int i = 0; i < names.length; i++) {if (names[i].equals(name)) {imageId = blackId[i]; break; }}}}// 获取棋编号public int getNum() {return num; }// 获取棋的颜色public int getPlayer() {return player; }// 获取棋名public String getName() {return name; }// 获取棋的图片idpublic int getImageId() {return imageId; }// 设置棋的行列坐标public void setPos(int posX, int posY) {this.posX = posX; this.posY = posY; }// 设置棋的航坐标public int getPosX() {return posX; }// 设置棋的列坐标public int getPosY() {return posY; }// 将当前的棋坐标水平翻转public void reverse() {posX = 9 - posX; }}

主机类:

package chinachess; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import chinachess.Chess; import chinachess.MainActivity; import com.example.l_b.chinachess.R; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class ServerView extends View {// private static final String TAG = "qaq"; // 棋的颜色public static final int BLACK = 1; public static final int RED = 2; // 设置棋盘的位置,视情况而定public static final int MARGINTOP = 150; public static final int MARGINLEFT = 83; // 每个格子的宽度public static final int W = 114; // 棋的总数public static final int ALLCHESS = 32; // 棋盘的行public static final int ROW = 10; // 棋盘的列public static final int COL = 9; // 没有棋的棋盘坐标的标记public static final int NULL = -1; // 接受消息端口private int receiverPort; // 发送消息端口private int sendPort; // 对方 ipprivate String ip; // 主活动private MainActivity context; // 所有的棋private Chess[] allChess = new Chess[ALLCHESS]; // 棋盘private int[][] map = new int[ROW][COL]; // 当前是否可以点击private boolean canPlay; // 判断是否移动了,只可处理点击事件private boolean isMove; // 设置我方的棋的颜色private int player; // 记录第一次选择的棋private Chess firstSelect; // 用于提示消息private TextView tvTip; // 判断当前是否赢了private boolean isWin; private Button btnNewGame; // 通过构造方法将一些重要参数传入进来public ServerView(Context context, int receiverPort, int sendPort, String ip) {super(context); this.receiverPort = receiverPort; this.sendPort = sendPort; this.ip = ip; this.context = (MainActivity) context; // 添加一个可以重新开始的按钮ViewGroup.LayoutParams param = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 120); btnNewGame = new Button(context); // 开始游戏后才可以点击btnNewGame。setEnabled(false); btnNewGame.setX(10); btnNewGame.setY(10); btnNewGame.setBackgroundResource(R.drawable.btn_blue); btnNewGame.setText("重新开始"); btnNewGame.setTextColor(Color.WHITE); btnNewGame.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 重新开始游戏restartGame(); sendMes("restart|"); }}); this.context.addContentView(btnNewGame, param); // 添加用于提示的文本框tvTip = new TextView(context); tvTip.setX(300); tvTip.setY(10); this.context.addContentView(tvTip, param); // 初始化棋盘initMapAndChess(); // 设置触屏事件setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// 若当前不可以点击则不执行点击事件if (!canPlay) {return false; }switch (event.getAction()) {case MotionEvent.ACTION_DOWN:isMove = false; break; case MotionEvent.ACTION_MOVE:// 若有滑动事件则会执行isMove = true; break; case MotionEvent.ACTION_UP:if (!isMove) {// 获取点击的 x 坐标int x = ((int) event.getX() - MARGINLEFT); // 获取点击的 y 坐标int y = ((int) event.getY() - MARGINTOP - MARGINLEFT); // 转化为棋盘的 col 列坐标// x % W > W / 2 ? 1 : 0 为当前的位置的求模后是否满足大于一半的宽度,// 若大于则把它安排到下一个位置,否则不变x = x / W + (x % W > W / 2 ? 1 : 0); // 转化为棋盘的 row 行坐标y = y / W + (y % W > W / 2 ? 1 : 0); // 若超出棋盘边界则不执行if (x < 0 || x >= COL || y < 0 || y >= ROW) {break; }// 如果为第一次点击if (firstSelect == null) {// 若当前点击的位置是空的if (map[y][x] == NULL) {break; }// 创建一个临时变量来存储当前位置上的棋Chess temp = allChess[map[y][x]]; // 若点击的是对方的棋if (temp.getPlayer() != player) {break; }// 存起来firstSelect = temp; // 更新视图invalidate(); } else {// 已选择第一个棋后// 若当前位置为空棋时if (map[y][x] == NULL) {// 若能移动if (canMove(y, x)) {// 获取第一次选择的棋的编号, 范围为 0,1,2,3...31; int pos = map[firstSelect.getPosX()][firstSelect.getPosY()]; // 将第一次选择的棋编号给第二次选择的位置map[y][x] = pos; // 将第一次选择的棋编号置空map[firstSelect.getPosX()][firstSelect.getPosY()] = NULL; // 将第一次选择的棋的位置改变为当前位置firstSelect.setPos(y, x); // 轮到对方下canPlay = false; // 将存储的第一个棋置空firstSelect = null; // 发送我方移动信息给客户单,“|” 为分隔符,用于分割信息,// 最后要用 "|" 结尾,不然最后一个信息个出错sendMes("move|" + pos + "|" + y + "|" + x + "|"); // 设置提示消息tvTip.setText("对方下"); // 更新视图invalidate(); }} else {// 若当前的位置不为空棋// 获取当前的棋编号int pos = map[y][x]; // 若当前的棋为我方棋时,则把第一次选择的棋替换为当前棋if (allChess[pos].getPlayer() == player) {firstSelect = allChess[pos]; invalidate(); } else {// 是否可以移动if (canMove(y, x)) {// 将第一次选择的棋编号置空map[firstSelect.getPosX()][firstSelect.getPosY()] = NULL; // 将第一次选择的棋编号给第二次选择的位置map[y][x] = firstSelect.getNum(); // 将第一次选择的棋的位置改变为当前位置firstSelect.setPos(y, x); // 发送我方移动信息给客户单sendMes("move|" + firstSelect.getNum() + "|" + y + "|" + x + "|"); // 若当前吃掉的棋为帅时if ("帅".equals(allChess[pos].getName())) {sendMes("winner|"); tvTip.setText("我方获胜"); } else {tvTip.setText("对方下"); }// 将存储的第一个棋置空firstSelect = null; // 将吃掉得棋置空allChess[pos] = null; // 轮到对方下canPlay = false; invalidate(); }}}}}}return true; }}); }// 判断是否可以移动private boolean canMove(int r2, int c2) {// 要移动的棋名String name = firstSelect.getName(); // 存储第一次的行坐标int r1 = firstSelect.getPosX(); // 存储第一次的列坐标int c1 = firstSelect.getPosY(); if ("帅".equals(name)) {// 只能直线移动if (r1 != r2 && c1 != c2) {return false; }// 判断是否可以将军if (map[r2][c2] != NULL && "帅".equals(allChess[map[r2][c2]].getName())) {// 保持 r1 一定小于 r2// c1 一定等于 c2if (r1 > r2) {int t = r1; r1 = r2; r2 = t; }// 标记两个帅之间是否有棋子,若有,则不可以移动boolean flag = true; for (int i = r1 + 1; i < r2 && flag; i++) {if (map[i][c1] != NULL) {flag = false; }}return flag; // 只可移动一格} else if (Math.abs(c1 - c2) != 1 && Math.abs(r2 - r1) != 1) {return false; }// 只可在田字中移动return r2 >= 7 && c2 >= 3 && c2 <= 5; } else if ("士".equals(name)) {// 不能直线移动if (r1 == r2 || c1 == c2) {return false; }// 只能移动一格if (Math.abs(r1 - r2) != 1 || Math.abs(c1 - c2) != 1) {return false; }// 只可在田字中移动return r2 >= 7 && c2 >= 3 && c2 <= 5; } else if ("相".equals(name)) {// 不可以过河,越界if (r2 <= 4) {return false; }// 只能走田字if (Math.abs(r1 - r2) != 2 || Math.abs(c1 - c2) != 2) {return false; }// 是否被挡住了return map[(r1 + r2) / 2][(c1 + c2) / 2] == NULL; } else if ("马".equals(name)) {// 只能走 日 字if (Math.abs(r1 - r2) * Math.abs(r1 - r2) + Math.abs(c1 - c2) * Math.abs(c1 - c2) != 5) {return false; }// 向下走时if (r2 - r1 == 2) {// 是否被挡住了if (map[r1 + 1][c1] != NULL) {return false; }// 向上走时} else if (r2 - r1 == -2) {if (map[r1 - 1][c1] != NULL) {return false; }// 向左走时} else if (c2 - c1 == 2) {if (map[r1][c1 + 1] != NULL) {return false; }// 向右走时} else if (c2 - c1 == -2) {if (map[r1][c1 - 1] != NULL) {return false; }}} else if ("车".equals(name)) {// 只能直线移动if (r2 != r1 && c2 != c1) {return false; }// 一个临时变量int t; // 左右走if (r2 == r1) {// 确保 c1 一定 小于 c2if (c1 > c2) {t = c1; c1 = c2; c2 = t; }// 之间是否被挡住了for (int i = c1 + 1; i < c2; i++) {if (map[r1][i] != NULL) {return false; }}} else {// 上下走// 确保 r1 一定 小于 r2if (r1 > r2) {t = r1; r1 = r2; r2 = t; }for (int i = r1 + 1; i < r2; i++) {if (map[i][c1] != NULL) {return false; }}}} else if ("炮".equals(name)) {// 只能走直线if (r1 != r2 && c1 != c2) {return false; }int t; // 平常走时,跟车一样if (map[r2][c2] == NULL) {if (r2 == r1) {// 确保 c1 一定在 c2 的上面if (c1 > c2) {t = c1; c1 = c2; c2 = t; }for (int i = c1 + 1; i < c2; i++) {if (map[r1][i] != NULL) {return false; }}} else {if (r1 > r2) {t = r1; r1 = r2; r2 = t; }for (int i = r1 + 1; i < r2; i++) {if (map[i][c1] != NULL) {return false; }}}// 可以吃子时} else {// 用于记录之间有几个棋子,只能为一int count = 0; if (r2 == r1) {// 确保 c1 一定在 c2 的上面if (c1 > c2) {t = c1; c1 = c2; c2 = t; }for (int i = c1 + 1; i < c2; i++) {if (map[r1][i] != NULL) {count++; if (count > 1) {return false; }}}} else {if (r1 > r2) {t = r1; r1 = r2; r2 = t; }for (int i = r1 + 1; i < r2; i++) {if (map[i][c1] != NULL) {count++; if (count > 1) {return false; }}}}if (count != 1) {return false; }}} else if ("卒".equals(name)) {// 只能往前走if (r2 > r1) {return false; }// 若过河了if (r1 <= 4) {// 只能走直线if (r2 != r1 && c2 != c1) {return false; }// 只能走一格if (Math.abs(c1 - c2) != 1 && r1 - r2 != 1) {return false; }} else {// 若没有过河,则只能前走一格if (c2 != c1 || r1 - r2 != 1) {return false; }}}return true; }private void initMapAndChess() {// 将编号全置空for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {map[i][j] = NULL; }}// 将,两士,两相,两马,两车,两炮,五卒// 32 个棋子在地图上的 x 坐标,红棋先// 前16个棋的 x 坐标int[] mapX = {4, 3, 5, 2, 6, 1, 7, 0, 8, 1, 7, 0, 2, 4, 6, 8}; // 前16个棋的 y 坐标int[] mapY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, 3}; // 前16个棋的棋名String[] strings = {"帅", "士", "士", "相", "相", "马", "马", "车", "车", "炮", "炮", "卒", "卒", "卒", "卒", "卒"}; // 临时存储行和列int row, col; for (int i = 0; i < allChess.length; i++) {// 小于16为红旗if (i < 16) {row = mapY[i]; col = mapX[i]; // 初始化棋子allChess[i] = new Chess(RED, strings[i], i); // 给相应的棋盘位置安排编号map[row][col] = i; // 设置棋子在棋盘中的初始位置allChess[i].setPos(row, col); } else {row = ROW - mapY[i - 16] - 1; col = COL - mapX[i - 16] - 1; allChess[i] = new Chess(BLACK, strings[i - 16], i); map[row][col] = i; allChess[i].setPos(row, col); }}//showChess(); }//private void showChess() {//String s; //for (int i = 0; i < ROW; i++) {//s = ""; //for (int j = 0; j < COL; j++) {//s += map[i][j] + " "; //}//Log.d(TAG, "showChess: " + s); //}//for (int i = 0; i < allChess.length; i++) {//Log.d(TAG, "showChess: " + allChess[i].getName() + "-" + allChess[i].getNum() + "-" + allChess[i].getPosX() + "-" + allChess[i].getPosY()); //}//}// 翻转棋盘private void reverseMap() {int t; // 默认为黑下红上// 主机为黑下红上// 客户端为黑上红下,所以是客户端时将双方棋的位置换一下for (int i = 0; i < ROW / 2; i++) {for (int j = 0; j < COL; j++) {t = map[i][j]; map[i][j] = map[ROW - i - 1][j]; map[ROW - i - 1][j] = t; }}for (Chess c : allChess) {c.reverse(); }//showChess(); }public void startServer() {// 将主活动的辅助控件隐藏掉context.uiGone(); tvTip.setText("等待连接..."); // 开启接收信息的线程new MessageThread().start(); }public void sendMes(final String s) {// 发送信息,要在线程里执行(异步执行)new Thread(new Runnable() {@Overridepublic void run() {DatagramSocket ds = null; try {ds = new DatagramSocket(); byte[] buffer; buffer = s.getBytes(); InetAddress ia = InetAddress.getByName(ip); DatagramPacket dp = new DatagramPacket(buffer, buffer.length, ia, sendPort); ds.send(dp); } catch (IOException e) {e.printStackTrace(); } finally {if (ds != null) {ds.close(); }}}}).start(); }// 每次调用 invalidate 就会执行这个方法@Overrideprotected void onDraw(Canvas canvas) {// 画笔,用于设置线条样式Paint paint = new Paint(); paint.setStrokeWidth(5); paint.setStyle(Paint.Style.STROKE); // 设置棋盘图片,宽高视手机分辨率而定canvas.drawBitmap(getBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bg), 1080, 1195), 0, MARGINTOP, paint); // 画棋for (Chess allChes : allChess) {// 若没有被吃掉if (allChes != null) {// x 坐标为列坐标乘以格子的宽度然后减去一半的格子宽度,让棋子的中心对齐坐标顶点int x = allChes.getPosY() * W + MARGINLEFT - W / 2; int y = allChes.getPosX() * W + MARGINTOP + MARGINLEFT - W / 2; canvas.drawBitmap(getBitmap(BitmapFactory.decodeResource(getResources(), allChes.getImageId()), W, W), x, y, paint); }}// 若第一次选择了则画一个矩阵边框来显示已选中if (firstSelect != null) {paint.setColor(Color.RED); int x = firstSelect.getPosY() * W + MARGINLEFT - W / 2; int y = firstSelect.getPosX() * W + MARGINTOP + MARGINLEFT - W / 2; // 画线int[] posX = {x, x + W, x + W, x, x}; int[] posY = {y, y, y + W, y + W, y}; Path path = new Path(); path.moveTo(posX[0], posY[0]); for (int i = 1; i < posX.length; i++) {path.lineTo(posX[i], posY[i]); }canvas.drawPath(path, paint); }}// 自定义图片宽高private Bitmap getBitmap(Bitmap rootImg, int w, int h) {int rW = rootImg.getWidth(); int rH = rootImg.getHeight(); Matrix matrix = new Matrix(); matrix.postScale(w * 1.0f / rW, h * 1.0f / rH); return Bitmap.createBitmap(rootImg, 0, 0, rW, rH, matrix, true); }// 重新开始游戏private void restartGame() {// 重新初始化棋盘initMapAndChess(); // 若是黑棋则先下canPlay = true; String tip = "已重新开始游戏,我下"; if (player == RED) {reverseMap(); canPlay = false; tip = "已重新开始游戏,对方下"; }isWin = false; // 给提示,在线程中更新 UI 时需转到主线程上setTip(tip); // 刷新视图updateOnUI(); }// 接受信息的线程class MessageThread extends Thread {@Overridepublic void run() {try {DatagramSocket ds = new DatagramSocket(receiverPort); byte[] buffer = new byte[100]; DatagramPacket dp = new DatagramPacket(buffer, buffer.length); // 发送加入信息sendMes("join|"); while (true) {ds.receive(dp); String s = new String(buffer); // 指定分割符分割信息String[] array = s.split("\\|"); switch (array[0]) {// 只有主机才会接收到case "join":player = BLACK; canPlay = true; sendMes("conn|"); setTip("我是黑棋,我下"); context.runOnUiThread(new Runnable() {@Overridepublic void run() {btnNewGame.setEnabled(true); }}); break; // 只有客户端才会接收到case "conn":player = RED; // 要翻转棋盘reverseMap(); updateOnUI(); canPlay = false; setTip("我是红棋,对方下"); context.runOnUiThread(new Runnable() {@Overridepublic void run() {btnNewGame.setEnabled(true); }}); break; // 接受到了移动信息case "move":// 判断是否赢了,若赢了则后面的不执行if (isWin) {continue; }// 对方走的棋编号int originalPos = Integer.valueOf(array[1]); // 要走的行坐标int y2 = ROW - Integer.valueOf(array[2]) - 1; // 要走的列坐标int x2 = Integer.valueOf(array[3]); // 我方当前的对方要走的棋行列坐标int y1 = allChess[originalPos].getPosX(); int x1 = allChess[originalPos].getPosY(); // 存储要走向的坐标在棋盘的编号int movePos = map[y2][x2]; // 将原来的位置置空map[y1][x1] = NULL; // 要走的位置设置为对方的棋编号map[y2][x2] = originalPos; // 更新其坐标allChess[originalPos].setPos(y2, x2); // 判断要走的位置是否有棋,若有,则置空if (movePos != NULL && allChess[movePos] != null) {allChess[movePos] = null; }// 更新视图updateOnUI(); // 我方可以下棋canPlay = true; setTip("我下"); break; // 对方赢了case "winner":isWin = true; whoWin(); break; // 重新开始游戏case "restart":restartGame(); break; }}} catch (IOException e) {e.printStackTrace(); }}}// 有赢家后private void whoWin() {canPlay = false; setTip("对方获胜"); }// 更新视图private void updateOnUI() {context.runOnUiThread(new Runnable() {@Overridepublic void run() {invalidate(); }}); }// 设置提示信息private void setTip(final String s) {context.runOnUiThread(new Runnable() {@Overridepublic void run() {tvTip.setText(s); }}); }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读