Java Listview致命异常:从doInBackground内部调用时异步任务#1
我正在通过客户端/服务器进行简单的聊天,当我将消息发送到服务器时,它完美地显示了ListView气泡。但是当我从服务器发送一个,客户端收到它时,它会尝试执行addItems(),然后关闭。我什么都试过了。我知道这是因为我不能从Asynctask更改UI,但我是Android/Java新手,我不知道该做什么!!请帮忙Java Listview致命异常:从doInBackground内部调用时异步任务#1,java,android,android-widget,android-listview,android-asynctask,Java,Android,Android Widget,Android Listview,Android Asynctask,我正在通过客户端/服务器进行简单的聊天,当我将消息发送到服务器时,它完美地显示了ListView气泡。但是当我从服务器发送一个,客户端收到它时,它会尝试执行addItems(),然后关闭。我什么都试过了。我知道这是因为我不能从Asynctask更改UI,但我是Android/Java新手,我不知道该做什么!!请帮忙 ***MY LOG CAT** 01-08 18:32:41.023: E/AndroidRuntime(1242): FATAL EXCEPTION: AsyncTask #1 0
***MY LOG CAT** 01-08 18:32:41.023: E/AndroidRuntime(1242): FATAL EXCEPTION: AsyncTask #1
01-08 18:32:41.023: E/AndroidRuntime(1242): java.lang.RuntimeException: An error occured while executing doInBackground()
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.lang.Thread.run(Thread.java:856)
01-08 18:32:41.023: E/AndroidRuntime(1242): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4609)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:835)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.View.requestLayout(View.java:15129)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.View.requestLayout(View.java:15129)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.View.requestLayout(View.java:15129)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.View.requestLayout(View.java:15129)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.view.View.requestLayout(View.java:15129)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.AbsListView.requestLayout(AbsListView.java:1932)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:813)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6051)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.widget.ArrayAdapter.add(ArrayAdapter.java:182)
01-08 18:32:41.023: E/AndroidRuntime(1242): at com.i911.emergency.response.DiscussArrayAdapter.add(DiscussArrayAdapter.java:26)
01-08 18:32:41.023: E/AndroidRuntime(1242): at com.i911.emergency.response.HelloBubblesActivity.addItems(HelloBubblesActivity.java:148)
01-08 18:32:41.023: E/AndroidRuntime(1242): at com.i911.emergency.response.HelloBubblesActivity.access$0(HelloBubblesActivity.java:147)
01-08 18:32:41.023: E/AndroidRuntime(1242): at com.i911.emergency.response.HelloBubblesActivity$TcpClientTask.doInBackground(HelloBubblesActivity.java:116)
01-08 18:32:41.023: E/AndroidRuntime(1242): at com.i911.emergency.response.HelloBubblesActivity$TcpClientTask.doInBackground(HelloBubblesActivity.java:1)
01-08 18:32:41.023: E/AndroidRuntime(1242): at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-08 18:32:41.023: E/AndroidRuntime(1242): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
01-08 18:32:41.023: E/AndroidRuntime(1242): ... 5 more
这是我的密码:
package com.ChatWithMe;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import com.ChatWithMe.OneComment;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class HelloBubblesActivity extends Activity {
private com.ChatWithMe.DiscussArrayAdapter adapter;
private ListView lv;
private EditText editText1;
public Socket s;
public BufferedWriter out;
public BufferedReader in;
public TextView i911Log;
public EditText DataToSend;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discuss);
lv = (ListView) findViewById(R.id.listView1);
adapter = new DiscussArrayAdapter(getApplicationContext(), R.layout.listitem_discuss);
lv.setAdapter(adapter);
new TcpClientTask().execute();
editText1 = (EditText) findViewById(R.id.editText1);
editText1.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
adapter.add(new OneComment(false, "User: " + editText1.getText().toString()));
adapter.add(new OneComment(true, "User: " + editText1.getText().toString()));
try {
out.write("TXT:" + editText1.getText().toString());
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
adapter.add(new OneComment(false, "Error Sending: " + editText1.getText().toString()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
adapter.add(new OneComment(false, "Error Sending: " + editText1.getText().toString()));
Log.i("TcpClient", "Button Clicked, but IOException Occured");
}
editText1.setText("");
return true;
}
return false;
}
});
}
class TcpClientTask extends AsyncTask<Void, Void, Void> {
private static final int TCP_SERVER_PORT = 1234;
private boolean error = false;
Boolean SocketStarted = false;
private BufferedReader in;
protected Void doInBackground(Void... arg0) {
try {
Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
//10.0.2.2
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "VER:Android,ID:1038263,SND:1,VDO:1,GPS:1,";
out.write(outMsg);
out.flush();
String outMsg2 = com.ChatWithMe.MainActivity.GPSTracker.toString();
out.write(outMsg2);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
String WhatsIN = in.readLine();
while(WhatsIN!=null){
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
String inMsg3 = inMsg.substring(1,inMsg.length() - 1);
Log.i("Info", "info: " + inMsg3);
if (inMsg3.equals("GPSX")) {
String GPSTracking = com.ChatWithMe.MainActivity.GPSTracker.toString();
Log.i("GPSX", "Sent:" + GPSTracking.toString());
out.write(GPSTracking);
out.flush();
}
// Check Commands
String CmdCheck = inMsg3.substring(0,4);
if (CmdCheck.equals("TXT:")) {
String SpitItOut = inMsg3.substring(4, inMsg3.length() - 1);
Log.i("SpitItOut", "Msg:" + SpitItOut.toString());
//ERROR IS HERE
addItems();
//ERROR IS HERE
}
}
} catch (UnknownHostException e) {
error = true;
e.printStackTrace();
} catch (IOException e) {
error = true;
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
if(error) {
// Something bad happened
}
else {
// Success
}
}
}
private void addItems() {
adapter.add(new OneComment(true, "Hello bubbles!"));
}
package.com.ChatWithMe;
导入java.io.BufferedReader;
导入java.io.BufferedWriter;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.io.OutputStreamWriter;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入com.ChatWithMe.OneComment;
导入android.app.Activity;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.KeyEvent;
导入android.view.view;
导入android.view.view.OnKeyListener;
导入android.widget.EditText;
导入android.widget.ListView;
导入android.widget.TextView;
公共类HelloBubblesActivity扩展了活动{
private com.ChatWithMe.discussarayaAdapter适配器;
私有ListView lv;
私人编辑文本编辑文本1;
公共插座;
公共缓冲写出来;
公共缓冲区中的读卡器;
公共文本视图i911Log;
公共编辑文本数据发送;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_discussion);
lv=(ListView)findViewById(R.id.listView1);
adapter=new DiscussArrayAdapter(getApplicationContext(),R.layout.listitem\u discus);
低压设置适配器(适配器);
新的TcpClientTask().execute();
editText1=(EditText)findViewById(R.id.editText1);
editText1.setOnKeyListener(新的OnKeyListener(){
公共布尔onKey(视图v、int keyCode、KeyEvent事件){
//如果事件是“回车”按钮上的按键按下事件
如果((event.getAction()==KeyEvent.ACTION\u DOWN)&&(keyCode==KeyEvent.keyCode\u ENTER)){
//在按键时执行操作
add(新的OneComment(false,“用户:+editText1.getText().toString());
add(新的OneComment(true,“用户:+editText1.getText().toString());
试一试{
out.write(“TXT:+editText1.getText().toString());
out.flush();
}捕获(未知后异常e){
e、 printStackTrace();
add(newOneComment(false,“发送错误:+editText1.getText().toString());
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
add(newOneComment(false,“发送错误:+editText1.getText().toString());
Log.i(“TcpClient”,“单击按钮,但发生IOException”);
}
editText1.setText(“”);
返回true;
}
返回false;
}
});
}
类TcpClientTask扩展了异步任务{
专用静态最终int TCP_服务器_端口=1234;
私有布尔错误=false;
布尔SocketStarted=false;
中的私有缓冲区读取器;
受保护的Void doInBackground(Void…arg0){
试一试{
套接字s=新套接字(“10.0.2.2”,TCP\u服务器\u端口);
//10.0.2.2
in=新的BufferedReader(新的InputStreamReader(s.getInputStream());
out=新的BufferedWriter(新的OutputStreamWriter(s.getOutputStream());
//发送输出消息
String outMsg=“版本:Android,ID:1038263,SND:1,VDO:1,GPS:1,”;
out.write(outMsg);
out.flush();
String out msg2=com.ChatWithMe.MainActivity.GPSTracker.toString();
out.write(outMsg2);
out.flush();
Log.i(“TcpClient”,“sent:”+outMsg);
字符串WhatsIN=in.readLine();
while(WhatsIN!=null){
字符串inMsg=in.readLine()+System.getProperty(“line.separator”);
Log.i(“TcpClient”,“received:”+inMsg);
字符串inMsg3=inMsg.substring(1,inMsg.length()-1);
Log.i(“Info”,“Info:+inMsg3”);
if(inMsg3.equals(“GPSX”)){
字符串gpstrack=com.ChatWithMe.MainActivity.GPSTracker.toString();
Log.i(“GPSX”,“Sent:”+GPSTracking.toString());
out.write(GPSTracking);
out.flush();
}
//检查命令
字符串CmdCheck=inMsg3.substring(0,4);
if(CmdCheck.equals(“TXT:”){
字符串SpitOut=inMsg3.substring(4,inMsg3.length()-1);
Log.i(“SpitOut”,“Msg:+SpitOut.toString());
//错误就在这里
addItems();
//错误就在这里
}
}
}捕获(未知后异常e){
错误=真;
e、 printStackTrace();
}捕获(IOE异常){
错误=真;
e、 printStackTrace();
}
返回null;
}
受保护的void onPostExecute(){
如果(错误){
//发生了不好的事
}
否则{
//成功
}
}
}
私有void附加项(){
add(newonecomment(true,“hellobuses!”);
}
}将附加项()移动到onPostExecute()
。您不能在后台线程中修改任何与UI相关的内容。了解异步任务。基本上,您有在UI线程上运行的onPostExecute()
方法,您应该将doInBackground()
的结果传递给它,并修改UI或在主线程中必须执行的任何操作。所以您的addItems()
方法会产生错误,因为您正试图从后台线程更改适配器。将其移入onPostExecute()