【发布时间】:2021-06-28 05:29:37
【问题描述】:
我正在开发一个包含三个 WiFi 模块“ESP8266-01”(它们代表三个服务器)的项目,我想同时读取所有这些模块。
我想通过在一个单独的线程上运行三个客户端来实现这一点。
我为此目的创建了一个特殊类(称为 IMU1)并在 PC 上运行它,它工作正常,但是当我尝试将此程序移动到 android 时,当我按下按钮时它给了我这个错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: client.app.recrive, PID: 4416
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:4438)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:4438)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
at libcore.io.IoBridge.recvfrom(IoBridge.java:506)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
at java.io.InputStreamReader.read(InputStreamReader.java:233)
at java.io.BufferedReader.fillBuf(BufferedReader.java:145)
at java.io.BufferedReader.readLine(BufferedReader.java:397)
at client.app.recrive.IMU1.read(IMU1.java:45)
at client.app.recrive.MainActivity.receiveData(MainActivity.java:27)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:4438)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
主活动:
package client.app.recrive;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.net.*;
import java.io.*;
import client.app.recrive.IMU1;
public class MainActivity extends AppCompatActivity {
private Button btn;
private TextView tv;
private EditText txt;
public void receiveData(View v) throws IOException , InterruptedException{
IMU1 imu = new IMU1("192.168.1.7", 8080, 1);
imu.start();
//wait until the connection is complete
Thread.sleep(100);
this.tv.setText(imu.read());
imu.join();
Log.d("wifi","finished");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.btn = findViewById(R.id.button);
this.txt = findViewById(R.id.text);
this.tv = findViewById(R.id.textView);
this.tv.setText("");
}
}
IMU1 类:
package client.app.recrive;
import java.net.*;
import java.io.*;
import android.util.Log;
class IMU1 extends Thread {
private String ip = "";
private int port = 0;
private int id = 0;
private float q1 = 0;
private float q2 = 0;
private float q3 = 0;
private float q4 = 0;
private Socket socket;
private BufferedReader reader;
private InputStream input;
private String text;
public IMU1(String ip, int port, int id) {
this.ip = ip;
this.port = port;
this.id = id;
}
public synchronized void initialize() {
try {
Socket s = new Socket(this.ip, this.port);
this.socket = s;
BufferedReader r = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
this.reader = r;
} catch (IOException e) { e.printStackTrace();}
}
public String read() throws IOException {
if ((this.reader.readLine()) == null) { ///////////////////////// The Error!
return "Nothing!";
} else {
return this.reader.readLine().toString();
}
}
public void terminate() throws IOException {
this.socket.close();
this.reader.close();
//stop Thread
}
@Override
public void run() {
super.run();
this.initialize();
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/msg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="false"
android:layout_gravity="center"
android:orientation="vertical"
android:background="@color/gray"
tools:context=".MainActivity">
<EditText
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginTop="200dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="30dp"
android:ems="10"
android:hint="Message"
android:inputType="textPersonName"
android:textColor="@color/purple_700" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|center_horizontal"
android:layout_marginLeft="10dp"
android:layout_marginTop="30dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="30dp"
android:insetLeft="10dp"
android:insetRight="10dp"
android:onClick="receiveData"
android:text="Recieve"
app:backgroundTint="@color/purple_700" />
<TextView
android:id="@+id/textView"
android:layout_width="350dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="client.app.recrive">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Client">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我用来测试程序的三台服务器之一:
package server;
import java.net.*;
import java.io.*;
import java.util.Date;
public class server2 {
static Socket csk;
static byte[] data = { 111 };
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8080);
System.out.println("Listening for connection on port 8080 ....");
while (true) {
try (Socket socket = server.accept()) {
System.out.println("accepted");
String text = "Hello! from server2\n";
while(true) {
socket.getOutputStream().write(text.getBytes("UTF-8"));
//Thread.sleep(100);
}
}
}
} catch (Exception e2) {
System.out.println("Error" + e2);
}
}
}
这表明错误出现在if ((this.reader.readLine()) == null) 语句中,所以我反转了条件,但它不起作用。
【问题讨论】:
-
您确定允许
receiveData抛出已检查的Exceptions 吗?我在问,因为它用于onClick属性。 -
@gthanop 是对的。因为您不能只向用作 onClick 侦听器的方法签名添加异常
标签: java android multithreading android-studio sockets