我开始了一个项目,我希望将一些十六进制的颜色发送到我的Arduino,然后用这种颜色制作一个LED灯条。但我的问题是,每当我尝试向Arduino发送内容时,我都会在NetworkOnMainThreadException抛出的Android工作室中收到错误:
android.os.NetworkOnMainThreadException
W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
W/System.err: at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
W/System.err: at java.net.SocketOutputStream.write(SocketOutputStream.java:157)
W/System.err: at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
W/System.err: at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
W/System.err: at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
W/System.err: at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
W/System.err: at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
W/System.err: at java.io.BufferedWriter.flush(BufferedWriter.java:254)
W/System.err: at java.io.PrintWriter.flush(PrintWriter.java:320)
W/System.err: at com.example.marnaut.arduinoledcontroller.TCPClient.sendMessage(TCPClient.java:51)
W/System.err: at com.example.marnaut.arduinoledcontroller.ShutdownAsyncTask.onProgressUpdate(ShutdownAsyncTask.java:49)
W/System.err: at com.example.marnaut.arduinoledcontroller.ShutdownAsyncTask.onProgressUpdate(ShutdownAsyncTask.java:7)
W/System.err: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:687)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6121)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
我在GitHub上获得了应用程序的代码,并根据我的需要对其进行了转换。我有红色,SocketOutputStream错误也可能意味着Arduino没有收到任何东西,但它在我运行应用程序时确实会改变颜色,所以它收到了发送的消息。另外,当我用一台电脑正常连接telnet到Arduino时,我可以正常改变颜色。我也试图改变从println发送数据到打印或写入的方法,但都没有帮助。有人可以帮助我,因为我一直得到这个例外吗?
修改 我试图为AsyncTask添加一个新的线程策略:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);
有了这个我摆脱了错误信息,但我仍然从处理程序中得到错误......我也没有提到的是我使用了以下2个权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
MainActivity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final int CHANGED = 0;
public static final int SENDING = 1;
public static final int SENT = 2;
public static final int CONNECTING = 3;
public static final int ERROR = 4;
public static final int SHUTDOWN = 5;
Visualizer visual;
Handler mHandler;
private TextView redValue;
private TextView greenValue;
private TextView blueValue;
private SeekBar redSlider;
private SeekBar greenSlider;
private SeekBar blueSlider;
private Button sendBtn;
private String color = "000000";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case CHANGED:
Log.d(TAG, "Color changed.");
break;
case SENDING:
Log.d(TAG, "Sending data...");
break;
case SENT:
Log.d(TAG, "Data sent.");
break;
case CONNECTING:
Log.d(TAG, "Connecting...");
break;
case ERROR:
Log.d(TAG, "Error...");
break;
case SHUTDOWN:
Log.d(TAG, "Shutdown command recieved");
break;
}
}
};
redValue = (TextView) findViewById(R.id.redValue);
greenValue = (TextView) findViewById(R.id.greenValue);
blueValue = (TextView) findViewById(R.id.blueValue);
redSlider = (SeekBar) findViewById(R.id.redSlider);
greenSlider = (SeekBar) findViewById(R.id.greenSlider);
blueSlider = (SeekBar) findViewById(R.id.blueSlider);
sendBtn = (Button) findViewById(R.id.sendBtn);
sendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ShutdownAsyncTask(mHandler).execute("");
}
});
redSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
redValue.setText(String.valueOf(progress));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
greenSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
greenValue.setText(String.valueOf(progress));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
blueSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
blueValue.setText(String.valueOf(progress));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
TCP客户端:
public class TCPClient {
private static final String TAG = "TCPClient";
private final Handler mHandler;
private String ipNumber, incomingMessage, command;
private BufferedReader in;
private PrintWriter out;
private MessageCallback listener = null;
private boolean mRun = false;
public TCPClient(Handler mHandler, String command, String ipNumber, MessageCallback listener) {
this.listener = listener;
this.ipNumber = ipNumber;
this.command = command;
this.mHandler = mHandler;
}
public void sendMessage(String message) {
try {
if (out != null && !out.checkError()) {
out.write(message);
out.flush();
mHandler.sendEmptyMessageDelayed(MainActivity.SENDING, 1000);
Log.d(TAG, "Sent Message: " + message);
}
} catch (Exception e) {
mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 1000);
e.printStackTrace();
}
}
public void stopClient() {
Log.d(TAG, "Client stopped!");
mRun = false;
}
public void run() {
mRun = true;
try {
Log.d(TAG, "Connecting...");
InetAddress serverAddress = InetAddress.getByName(ipNumber);
mHandler.sendEmptyMessageDelayed(MainActivity.CONNECTING, 1000);
Socket socket = new Socket(serverAddress, 23);
Log.d(TAG, "Socket created with ip: " + ipNumber);
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d(TAG, "In/Out created");
this.sendMessage(command);
mHandler.sendEmptyMessageDelayed(MainActivity.SENDING, 2000);
while (mRun) {
incomingMessage = in.readLine();
if (incomingMessage != null && listener != null)
listener.callbackMessageReceiver(incomingMessage);
//incomingMessage = null;
}
Log.d(TAG, "Received Message: " + incomingMessage);
} catch (Exception e) {
Log.d(TAG, "Error", e);
mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);
} finally {
out.flush();
out.close();
in.close();
socket.close();
mHandler.sendEmptyMessageDelayed(MainActivity.SENT, 3000);
Log.d(TAG, "Socket Closed");
}
} catch (Exception e) {
Log.d(TAG, "Error in socket", e);
mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);
}
}
boolean isRunning() {
return mRun;
}
public interface MessageCallback {
void callbackMessageReceiver(String message);
}
}
的AsyncTask:
public class MyAsyncTask extends AsyncTask<String, String, TCPClient> {
private static final String COMMAND = "0xFFFF00";
private TCPClient tcpClient;
private Handler mHandler;
private static final String TAG = "MyAsyncTask";
public MyAsyncTask(Handler mHandler){
this.mHandler = mHandler;
}
@Override
protected TCPClient doInBackground(String... params) {
Log.d(TAG, "In: do in background");
try{
tcpClient = new TCPClient(mHandler, COMMAND, "192.168.0.190", new TCPClient.MessageCallback() {
@Override
public void callbackMessageReceiver(String message) {
publishProgress(message);
}
});
} catch (NullPointerException e){
Log.d(TAG, "Caught null pointer exception");
e.printStackTrace();
} catch (Exception e) {
Log.d(TAG, "Cought sth weird");
e.printStackTrace();
}
tcpClient.run();
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
for (String value : values)
Log.d(TAG, "In progress update, values: " + value);
Log.d(TAG, "#Values: " + values.length);
if(values[0].equals("Welcome!")){
tcpClient.sendMessage("0x00FF00");
tcpClient.stopClient();
mHandler.sendEmptyMessageDelayed(MainActivity.CHANGED, 2000);
}else{
tcpClient.sendMessage("0xFF0000");
mHandler.sendEmptyMessageDelayed(MainActivity.ERROR, 2000);
tcpClient.stopClient();
}
}
@Override
protected void onPostExecute(TCPClient result){
super.onPostExecute(result);
Log.d(TAG, "In on post execute");
if(result != null && result.isRunning()){
result.stopClient();
}
mHandler.sendEmptyMessageDelayed(MainActivity.SENT, 4000);
}
}