Android访问适配器时崩溃

时间:2014-07-27 08:37:21

标签: android

我对Android比较陌生。

我可以使用Socket.IO获取数据,但显然它在“adapter.notifyDataSetChanged();”崩溃了。动态更新ListActivity时。有没有人对如何更新它有更好的想法?

import android.os.Bundle;
import android.app.ListActivity;
import android.widget.ArrayAdapter;
import android.view.View;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import java.util.ArrayList;

import java.net.URISyntaxException;

import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
import com.github.nkzawa.emitter.Emitter;

public class MyActivity extends ListActivity {
    ArrayList<String> listItems=new ArrayList<String>();

    ArrayAdapter<String> adapter;

    Socket socket = null;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_my);
        adapter=new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1,
                listItems);
        setListAdapter(adapter);

        try {
            socket = IO.socket("http://192.168.1.174:10016");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

            @Override
            public void call(Object... args) {
                JSONObject obj = new JSONObject();
                try {
                    obj.put("hash", "#foo");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                socket.emit("connect_now", obj);
            }

        }).on("event", new Emitter.Listener() {

            @Override
            public void call(Object... args) {}

        }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {

            @Override
            public void call(Object... args) {}
        });

        socket.on("update_playlist", new Emitter.Listener() {
            @Override
            public void call(Object... args) {
                JSONObject obj = (JSONObject)args[0];
                JSONArray array = null;
                try {
                    array = obj.getJSONArray("content");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                for(int i = 0 ; i < array.length() ; i++){
                    try {
                        listItems.add(array.getJSONObject(i).toString());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                adapter.notifyDataSetChanged();
            }
        });

        socket.connect();
    }
}

我相信这是我得到的错误:

07-27 12:10:49.997    1955-1974/com.example.myapp.myapplication3 W/dalvikvm﹕ threadid=11: thread exiting with uncaught exception (group=0x416f7e18)
07-27 12:10:49.997    1955-1974/com.example.myapp.myapplication3 E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-9500
    Process: com.example.myapp.myapplication3, PID: 1955
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6454)
            at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:3049)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:650)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:650)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:650)
            at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:650)
            at android.view.View.setFlags(View.java:9008)
            at android.view.View.setFocusableInTouchMode(View.java:6182)
            at android.widget.AdapterView.checkFocus(AdapterView.java:718)
            at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:813)
            at android.widget.AbsListView$AdapterDataSetObserver.onChanged(AbsListView.java:6865)
            at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
            at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
            at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
            at com.example.myapp.myapplication3.MyActivity$5.call(MyActivity.java:96)

编辑。补充一点:

runOnUiThread(new Runnable() {
    public void run() {
        adapter.notifyDataSetChanged();
    }
});

现在它有效。抱歉造成麻烦。

1 个答案:

答案 0 :(得分:2)

您只能从主要或用户界面线程更新View个对象。

堆栈跟踪中的错误说明了问题所在(虽然可能不清楚):

  

只有创建视图层次结构的原始线程才能触及它   视图。

我们将应用程序的主线程称为UI线程,因为这是创建视图的线程。一旦你理解了这一点,那么错误就有意义了。


要从其他主题进行更新,请使用Activity.runOnUiThread(Runnable)View.post(Runnable)