03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: FATAL EXCEPTION: main
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: Process: tech.androidstudio.tulingdemo, PID: 16029
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: java.lang.IllegalStateException: Could not execute method for android:onClick
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:275)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View.performClick(View.java:4761)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:19767)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5310)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:270)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View.performClick(View.java:4761)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:19767)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5310)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.os.Handler.sendMessage(android.os.Message)' on a null object reference
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at tech.androidstudio.tulingdemo.MainActivity.btnSendMessage(MainActivity.java:65)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:270)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View.performClick(View.java:4761)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:19767)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5310)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
原因分析 :
子线程handler 报错,是因为没有启动子线程就开始使用了。
解决办法:
在onCreate方法中启动Thread,千万别忘了Thread里面的this 参数,不然还会报错。
Thread thread = new Thread(this);
thread.start();
public class MainActivity extends AppCompatActivity implements Runnable {
private EditText mEditText;
private ListView mListView;
private List mData;
private ListViewAdapter mAdapter;
private Handler subHandler;
private Handler mainHandler;
private final int MAIN_HANDLER_ADD=98;
private final int SUB_HANDLER_ADD=998;
private final int SUB_HANDLER_EXIT=199;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText=(EditText)findViewById(R.id.editText);
mListView=(ListView)findViewById(R.id.listView);
mData = new ArrayList<>();
mAdapter = new ListViewAdapter(mData,this);
mListView.setAdapter(mAdapter);
mainHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
switch (what){
case MAIN_HANDLER_ADD:
String msg_reply = (String)msg.obj;
mData.add(msg_reply);
mAdapter.notifyDataSetChanged();
break;
}
}
};
//千万别忘了启动子线程,不然会报错
//Attempt to invoke virtual method 'boolean android.os.Handler.sendMessage(android.os.Message)' on a null object reference
Thread thread = new Thread(this);
thread.start();
}
public void btnSendMessage(View view) {
String message_send = mEditText.getText().toString();
if(message_send!=null){
mData.add(message_send);
mAdapter.notifyDataSetChanged();
//将要发送的消息发送给子线程,(给子线程的handler),因为耗时操作不能在主线程进行
// 然后子线程请求数据再返回给主线程(主线程的 handler),因为 子线程不能修改界面的UI
Message message = Message.obtain();
message.what=SUB_HANDLER_ADD;
message.obj=message_send;
subHandler.sendMessage(message);//之前报错的位置是这一步
}
}
@Override
public void run() {
//绑定 当前线程的Looper
Looper.prepare();
subHandler= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int what = msg.what;
switch (what){
case SUB_HANDLER_ADD:
//获取发送的消息,然后通过HttpUtils来发送,并且得到返回值,
//把这个返回值 再给主线程的 handler来处理。
//先写一个模拟数据 ,例如"收到了"发送给主线程。
Message message = Message.obtain();
message.what=MAIN_HANDLER_ADD;
message.obj="收到了";
mainHandler.sendMessage(message);
break;
case SUB_HANDLER_EXIT:
//在onDestroy里面停止这个Looper
Looper looper = Looper.myLooper();
looper.quit();
break;
}
}
};
//不停的循环 ,就像是while一样。
Looper.loop();
}
}