#正常功能没有问题,但是在点击设置以后会闪退,检查错误是没有在ui线程里面操作
package com.example.application0703_work01;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//TCP相关————————————————————————————————————————
public static boolean m_isConnected = false;//是否成功连接服务器
ReadWriteLock m_rwLock = new ReentrantReadWriteLock();
public static TcpClient myTcpClient;
//数据——————————————————————————————————————————————————————————
public static double[][] huishouPM = new double[4][3];//PM1-3
public static boolean[][] huishouVB = new boolean[4][13];//V1-V6,Va,泵1,泵2,压缩1,压缩2,正在回收,正在清理
public static double[][] chuxuguan = new double[6][2];
public static double[] chouzhenkongPM = new double[4];//PM1
public static boolean[][] chouzhenkongVB = new boolean[4][6];//V1-3,真空,罗茨,正在抽真空
public static double[] chongqiPM = new double[4];//PM2
public static boolean[][] chongqiVB = new boolean[4][4];//V1,Va,Vb,正在充气
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ini();
// tcpClient_Init("192.168.0.127",8080);//测试使用
tcpClient_Init("192.168.1.1",8887);//实际超表网络信息
// text();
}
//测试数据解析--0103103DFBE76C3DFBE76C3DFBE76C00001081+crc
// private void text(){
// String str = "0103103DFBE76C3DFBE76C3DFBE76C";
// int i = Integer.parseInt("1000010000001",2);
// str += String.format("%08x",i);
// Log.e("测试Main",i+"+"+str);
//
// analysisData(str);
// double stri = ieee754tofloat(hexTobytes(str));
// Log.e("测试Main",huishouPM[0][0]+"+"+huishouVB[0][0]+"+"+huishouVB[0][7]+stri);
// }
private void ini(){
Button button = (Button) findViewById(R.id.btn_hs);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_cxg);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_czk);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_cq);
button.setOnClickListener(this);
button = (Button) findViewById(R.id.btn_sz);
button.setOnClickListener(this);
}
@Override
public void onClick(View v){
if(v.getId() == R.id.btn_sz)
{
changeActivity("com.example.application.Main_SZ");
return;
}
if(!m_isConnected)
{
Toast.makeText(MainActivity.this,"网络通讯异常,请检查网络或重新启动软件",Toast.LENGTH_LONG).show();
return;
}
if(v.getId() == R.id.btn_hs)
{
changeActivity("com.example.application.Main_HS");
}
else if (v.getId() == R.id.btn_cxg)
{
changeActivity("com.example.application.Main_CXG");
}
else if (v.getId() == R.id.btn_czk)
{
changeActivity("com.example.application.Main_CZK");
}
else if (v.getId() == R.id.btn_cq)
{
changeActivity("com.example.application.Main_CQ");
}
else {;}
}
private void changeActivity(String str) {
Intent intent = new Intent(str);
startActivity(intent);
}
/**
* 阀门状态解析
* @param boolArr 状态
* 回收阀门状态顺序: V1-V6,Va,泵1,泵2,压缩1,压缩2,正在回收,正在清理
* 抽真空阀门状态顺序: V1-3,真空,罗茨,正在抽真空
* 充气阀门状态顺序: V1,Va,Vb,正在充气
* @param status 状态字符串转成的int值
*/
private void valveStatus(boolean[] boolArr,int length,int status){
for(int i=0;i<length;i++)
{
boolArr[i] = ((status>>i)&1) !=0;
}
}
//str==010310 12345678 12345678 12345678 12345678 +crc
private void valueHuishou(int add,final String str){
if(Integer.valueOf(str.substring(4,6),16) != 16){
return;
}
int i = 6;
huishouPM[add-1][0]=ieee754tofloat(hexTobytes(str.substring(i,i+8)));
huishouPM[add-1][1]=ieee754tofloat(hexTobytes(str.substring(i+8,i+16)));
huishouPM[add-1][2]=ieee754tofloat(hexTobytes(str.substring(i+16,i+24)));
valveStatus(huishouVB[add-1],huishouVB[0].length,Integer.valueOf(str.substring(i+24,i+32),16));
}
//str==050308 12345678 12345678 +crc
private void valueChuxuguan(int add,final String str){
if(Integer.valueOf(str.substring(4,6),16) != 8){
return;
}
int i = 6;
chuxuguan[add-5][0]=ieee754tofloat(hexTobytes(str.substring(i,i+8)));
chuxuguan[add-5][1]=ieee754tofloat(hexTobytes(str.substring(i+8,i+16)));
}
//str==0B0308 12345678 12345678 +crc
private void valueChouzhenkong(int add,final String str){
if(Integer.valueOf(str.substring(4,6),16) != 8){
return;
}
int i = 6;
chouzhenkongPM[add-11]=ieee754tofloat(hexTobytes(str.substring(i,i+8)));
valveStatus(chouzhenkongVB[add-11],chouzhenkongVB[0].length,Integer.valueOf(str.substring(i+8,i+16),16));
}
//str==0f0308 12345678 12345678 +crc
private void valueChongqi(int add,final String str){
if(Integer.valueOf(str.substring(4,6),16) != 8){
return;
}
int i = 6;
chongqiPM[add-15]=ieee754tofloat(hexTobytes(str.substring(i,i+8)));
valveStatus(chongqiVB[add-15],chongqiVB[0].length,Integer.valueOf(str.substring(i+8,i+16),16));
}
//接收数据时调用,进行反馈数据的解析
private void analysisData(String str){
try {
m_rwLock.readLock().lock();
//str解析--暂时不用校验
// String crc = getCRC(str.substring(0,str.length()-5));
// if(crc != str.substring(str.length()-4,str.length()-1))
// {
// return;
// }
int add = Integer.valueOf(str.substring(0,2));
if(add==1 ||add==2 ||add==3 ||add==4){
valueHuishou(add,str);
}
else if (add==5 ||add==6 ||add==7 ||add==8 ||add==9 ||add==10) {
valueChuxuguan(add,str);
}
else if(add==11 ||add==12 ||add==13 ||add==14){
valueChouzhenkong(add,str);
}
else if(add==15 ||add==16 ||add==17 ||add==18){
valueChongqi(add,str);
}
else {;}
}finally {
m_rwLock.readLock().unlock();
}
}
//TCP连接线程--连接、接收、发送--------------------------------------------------------
private void tcpClient_Init(String ip,int port) {
if(myTcpClient!=null){//防止多个通道同时存在
myTcpClient.diConnect();
m_isConnected = false;
}
myTcpClient = new TcpClient();
new Thread(()->{
Log.e("测试TCP",ip+"+"+String.valueOf(port));
if(myTcpClient.connect(ip,port)){
rcvMsgHandler();
m_isConnected = true;
}else{
m_isConnected = false;
}
}).start();
}
private void rcvMsgHandler(){
new Thread(()->{
while (true){
if(myTcpClient.serverStatus != -1){
String msg = myTcpClient.rcvMsg();
if(msg != null){
analysisData(msg);
}
}else {
m_isConnected = false;
break;
}
}
}).start();
}
public static void send_Com(String msg){
//msg += getCRC(msg);//添加校验--暂时不用
final String str = msg ;
new Thread(()->{
if(myTcpClient.serverStatus != -1){
myTcpClient.sendMsg(str);
}else {
m_isConnected = false;
}
}).start();
}
//数据处理--------------------------------------------------------------------------
/**
* Hex转byte[]
* @param hex 两种情况,Hex长度为奇数最后一个字符会被舍去
* @return
*/
private byte[] hexTobytes(String hex) {
if (hex.length() < 1) {
return null;
} else {
byte[] result = new byte[hex.length() / 2];
int j = 0;
for (int i = 0; i < hex.length(); i += 2) {
result[j++] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
}
return result;
}
}
/**
* @Description: 计算CRC16校验码
*
* @param: str 需要转化为byte[]的字符串,转化结果举例:byte[] bytes = {(byte)0x00,(byte)0x17};
* @return: String 返回16进制字符串,结果举例:be41
*/
/**
* 获取校验码
* @param str 16进制字符串
* @return String 16进制字符串
*/
private String getCRC(String str) {
byte[] bytes = hexTobytes(str);
int CRC = 0x0000ffff;
int POLYNOMIAL = 0x0000a001;
int i, j;
for (i = 0; i < bytes.length; i++) {
CRC ^= (int) (bytes[i]) & 0x000000ff;
for (j = 0; j < 8; j++) {
if ((CRC & 0x00000001) != 0) {
CRC >>= 1;
CRC ^= POLYNOMIAL;
} else {
CRC >>= 1;
}
}
}
String crc = Integer.toHexString(CRC);
if (crc.length() == 2) {
crc = "00" + crc;
} else if (crc.length() == 3) {
crc = "0" + crc;
} else if (crc.length() == 1) {
crc = "000" + crc;
}
String[] crc1 = new String[] { crc.substring(0, 2), crc.substring(2) };
crc = crc1[1] + crc1[0];
// System.out.println(Integer.toHexString(CRC));
return crc.toUpperCase();
}
/**
* ieee754转float
* @param arr 高位在前
* @return float
*/
private float ieee754tofloat(byte[] arr) {
if(arr.length<4)
{
return 0;
}
int accum = 0;
accum = accum|(arr[3] & 0xff) << 0;
accum = accum|(arr[2] & 0xff) << 8;
accum = accum|(arr[1] & 0xff) << 16;
accum = accum|(arr[0] & 0xff) << 24;
return Float.intBitsToFloat(accum);
}
/**
* int 转换为 byte[]
* @param a
* @return
*/
private byte[] intToBytes(int a){
byte[] ans=new byte[4];
for(int i=0;i<4;i++)
ans[i]=(byte)(a>>(i*8));//截断 int 的低 8 位为一个字节 byte,并存储起来
return ans;
}
/**
* byte[] 转换为 int
* @param arr 高位在前
* @return int
*/
private static int bytesToInt(byte[] arr){
if(arr.length<4)
{
return 0;
}
int ans=0;
int accum = 0;
accum = accum|(arr[3] & 0xff) << 0;
accum = accum|(arr[2] & 0xff) << 8;
accum = accum|(arr[1] & 0xff) << 16;
accum = accum|(arr[0] & 0xff) << 24;
return ans;
}
}
#先解决ui线程问题,如果还是不行,再从其他方面找问题。
#安卓studio