尝试使用JSON信息更新片段中的列表

时间:2014-10-27 17:00:03

标签: java android json android-fragments android-listview

因此我尝试使用JSON传达的服务器提供的信息更新列表。

这是进行沟通的班级:

package com.example.simon_000.buddy;





 public class TCPConnection {
private RunOnThread thread;
private Receive receive;
private MainActivity ma;
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
private InetAddress address;
private int connectionPort;
private String ip;
private Exception exception;
public static String id;
public static ArrayList<members> memberList = new ArrayList<members>();
public static ArrayList<String> groupsList = new ArrayList<String>();
public static ArrayList<String> namesList = new ArrayList<String>();


public TCPConnection(String ip, int connectionPort, MainActivity ma) {
    this.ip = ip;
    this.connectionPort = connectionPort;
    thread = new RunOnThread();
    this.ma = ma;

}

public void connect() {
    thread.start();
    thread.execute(new Connect());
}

public void disconnect() {
    thread.execute(new Disconnect());
}

public void send(String expression) {
    thread.execute(new Send(expression));
}

private class Receive extends Thread {
    public void run() {
        String result;
        try {
            while (receive != null) {
                result = (String) input.readUTF();
                newMessage(result);
            }
        } catch (Exception e) { // IOException, ClassNotFoundException
            receive = null;
        }
    }
}

public void newMessage(final String answer) {
    ma.runOnUiThread(new Runnable() {
        public void run() {
            String message = answer;
            String type;

            JSONObject jObj = null;
            try {
                Log.d("TEST", message);
                jObj = new JSONObject(message);
                type = jObj.getString("type");

                if (type.equals("groups")) {
                    recevieGroups(jObj);
                }
                else if (type.equals("register")) {
                    recevieID(jObj);
                }
                else if (type.equals("members")) {
                    receiveMembers(jObj);
                }
                else if (type.equals("location")) {
                    receiveLocations(jObj);

                } else if (type.equals("locations")) {
                    receiveLocations(jObj);

                }


            } catch (JSONException e) {
                e.printStackTrace();
            }


        }
    });
}
public void receiveLocations(JSONObject jObj) throws JSONException {
     //        { ”type”:”locations”, ”group”:”NAME”, ”locations”:[ {”member”:”NAME”,   ”longitude”:”LONGITUDE”, ”latitude”:”LATITUDE” }, … ] }
    JSONArray jArray = jObj.getJSONArray("locations");

    for (int i = 0; i < jArray.length(); i++) {
        members m = new members();

        JSONObject jRealObject = jArray.getJSONObject(i);
        m.setName(jRealObject.getString("member"));
        m.setLongitude(Double.parseDouble(jRealObject.getString("longitude")));
        m.setLatitude(Double.parseDouble(jRealObject.getString("latitude")));
        memberList.add(m);
        Log.d("TEST", " memberNAMES : " + m.getName()+" lng: "+ m.getLongitude()+" lat: "+m.getLatitude());
    }
    ma.updateMapMarkers(memberList);
}
public void receiveMembers(JSONObject jObj) throws JSONException {
    //        { “type”:”members”, “group”:”NAME”, “members”:[ {“member”:”NAME”},…] }

    JSONArray jArray = jObj.getJSONArray("members");

    for (int i = 0; i < jArray.length(); i++) {
        String n;

        JSONObject jRealObject = jArray.getJSONObject(i);
        n = jRealObject.getString("member");
        Log.d("TEST", " MembernamesBEFORE_ADD : " + n );

        namesList.add(n);

        Log.d("TEST", " memberNAMES : " + n);
    }

}

public void recevieID(JSONObject jObj) throws JSONException {
    id = (jObj.getString("id"));
    Log.d("TEST", " ID : " + id);
}

public void recevieGroups(JSONObject jObj) throws JSONException {
    JSONArray jArray = jObj.getJSONArray("groups");

    for (int i = 0; i < jArray.length(); i++) {
        String g;
        JSONObject jRealObject = jArray.getJSONObject(i);
        g = (jRealObject.getString("group"));
        groupsList.add(g);
        Log.d("TEST", " groupNames : " + g);
    }
}

public Exception getException() {
    Exception result = exception;
    exception = null;
    return result;
}

private class Connect implements Runnable {
    public void run() {
        try {
            Log.d("TCPConnection", "Connect-run");
            address = InetAddress.getByName(ip);
            Log.d("TCPConnection-Connect", "Skapar socket");
            socket = new Socket(address, connectionPort);
            input = new DataInputStream(socket.getInputStream());
            output = new DataOutputStream(socket.getOutputStream());
            output.flush();
            Log.d("TCPConnection-Connect", "Strömmar klara");
            newMessage("CONNECTED");
            receive = new Receive();
            receive.start();
        } catch (Exception e) { // SocketException, UnknownHostException
            Log.d("TCPConnection-Connect", e.toString());
            exception = e;
            newMessage("EXCEPTION");
        }
    }
}

public class Disconnect implements Runnable {
    public void run() {
        try {
            if (socket != null)
                socket.close();
            if (input != null)
                input.close();
            if (output != null)
                output.close();
            thread.stop();
            newMessage("CLOSED");
        } catch (IOException e) {
            exception = e;
            newMessage("EXCEPTION");
        }
    }
}

public class Send implements Runnable {
    private String exp;

    public Send(String exp) {
        this.exp = exp;
    }

    public void run() {
        try {
            output.writeUTF(exp);
            output.flush();
        } catch (IOException e) {
            exception = e;
            newMessage("EXCEPTION");
        }
    }
}

 }

这是“控制器”:

package com.example.simon_000.buddy;





    public class MainActivity extends Activity
    implements NavigationDrawerFragment.NavigationDrawerCallbacks {

/**
 * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
 */
private NavigationDrawerFragment mNavigationDrawerFragment;


/**
 * Used to store the last screen title. For use in {@link #restoreActionBar()}.
 */
private CharSequence mTitle;
private myMap tempMapfragment = new myMap();
private Menu menu;
private String inetAddress = "195.178.232.7";
private Integer port = 7117;
private TCPConnection connect;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startNavDrawer();


    connect = new TCPConnection(inetAddress, port, this);
    connect.connect();
}

public void myPosition(String id, double LONGITUDE, double LATITUDE) {

    StringWriter stringWriter = new StringWriter();
    JsonWriter writer = new JsonWriter(stringWriter);
    try {
        writer.beginObject().name("type").value("location").name("id").value(id).name("longitude").value(LONGITUDE).name("latitude").value(LATITUDE).endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
    connect.send(stringWriter.toString());
}

public void getMembers(String group) {

    StringWriter stringWriter = new StringWriter();
    JsonWriter writer = new JsonWriter(stringWriter);
    try {
        writer.beginObject().name("type").value("members").name("group").value(group).endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
    connect.send(stringWriter.toString());
}

public void getGroups() {
     //    Aktuella grupper
      //    { ”type”:”groups” }
     //    { “type”:”groups”, ”groups”:[ {”group”:”NAME”}, …] }
    StringWriter stringWriter = new StringWriter();
    JsonWriter writer = new JsonWriter(stringWriter);
    try {
        writer.beginObject().name("type").value("groups").endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
    connect.send(stringWriter.toString());
}

public void registerGroup(String groupName, String userName) {
    StringWriter stringWriter = new StringWriter();
    JsonWriter writer = new JsonWriter(stringWriter);
    try {
        writer.beginObject().name("type").value("register").name("group").value(groupName).name("member").value(userName).endObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
    connect.send(stringWriter.toString());
}

public void updateMapMarkers(ArrayList<members> memberList) {
    for(members m: memberList){
        tempMapfragment.addMarker(m);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    connect.disconnect();
}


private void startNavDrawer() {
    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));
}

@Override
public void onNavigationDrawerItemSelected(int position) {
    // update the main content by replacing fragments
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    communication fragment2 = new communication();


    switch (position) {
        case 0:
            // fragment1
            // use fragment transaction and add the fragment to the container
            fragmentTransaction.replace(R.id.container, fragment2);
            fragmentTransaction.commit();

            break;
        case 1:
            // fragment2
            fragmentTransaction.replace(R.id.container, tempMapfragment);
            fragmentTransaction.commit();

            break;
        case 2:
            // fragment2
            break;
        default:
            // fragment1
            // use fragment transaction and add the fragment to the container


            fragmentTransaction.replace(R.id.container, fragment2);
            fragmentTransaction.commit();
    }

}


public void onSectionAttached(int number) {
    switch (number) {
        case 1:
            mTitle = getString(R.string.title_section1);
            break;
        case 2:
            mTitle = getString(R.string.title_section2);
            break;
        case 3:
            mTitle = getString(R.string.title_section3);
            break;
    }
}

public void restoreActionBar() {
    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setTitle(mTitle);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.menu = menu;
    if (!mNavigationDrawerFragment.isDrawerOpen()) {
        // Only show items in the action bar relevant to this screen
        // if the drawer is not showing. Otherwise, let the drawer
        // decide what to show in the action bar.
        getMenuInflater().inflate(R.menu.main, menu);
        restoreActionBar();
        return true;
    }
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //Setting maptype



    return super.onOptionsItemSelected(item);
}


/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {
    /**
     * The fragment argument representing the section number for this
     * fragment.
     */
    private static final String ARG_SECTION_NUMBER = "section_number";

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        ((MainActivity) activity).onSectionAttached(
                getArguments().getInt(ARG_SECTION_NUMBER));
    }
}

 }

这是片段,它在我打开Dialog onclick的部分。

package com.example.simon_000.buddy.Fragments;





public class communication extends Fragment {
private ListView list;
private EditText groupet;
private EditText nameet;
private ListView memberList;
private Button btsend, btUpdate;
private GroupAdapter Groupadapter;
private NameAdapter Nameadapter;

public communication() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_communication, container, false);
    getGroupInfo();
    initiateVariables(view);

    return view;
}

private void initiateVariables(View view) {
    list = (ListView) view.findViewById(R.id.grouplistView);
          //        groupsList = new ArrayList<String>();
       //        namesList = new ArrayList<String>();
    groupet = (EditText) view.findViewById(R.id.etgroupName);
    nameet = (EditText) view.findViewById(R.id.etUsername);
    btsend = (Button) view.findViewById(R.id.btSend);
    btUpdate = (Button) view.findViewById(R.id.btUpdate);
    groupet.setText("MadKim");
    Groupadapter = new GroupAdapter(getActivity(), R.layout.row, TCPConnection.groupsList);
    list.setAdapter(Groupadapter);
    list.setOnItemClickListener(new listListener());
    btsend.setOnClickListener(new Listener());
    btUpdate.setOnClickListener(new ListenerUpdate());
}
public void getGroupInfo(){
    ((MainActivity)getActivity()).getGroups();
}

private class Listener implements View.OnClickListener {
    @Override
    public void onClick(View view) {
           //            sc.startThreadCommunication();
        String group = groupet.getText().toString();
        String name = nameet.getText().toString();
           //            sending query to server
        if(group.isEmpty() || name.isEmpty() ){
            Toast.makeText(getActivity(), "You need to fill in all the fields.", Toast.LENGTH_LONG).show();
        }else {
            ((MainActivity)getActivity()).registerGroup(groupet.getText().toString(),       nameet.getText().toString());
            getGroupInfo();
            Groupadapter.notifyDataSetChanged();
            //hides keyboard
            nameet.clearFocus();
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
                    Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(nameet.getWindowToken(), 0);
            //show user info
            Toast.makeText(getActivity(), "Successfully registered to: "+groupet.getText().toString()+
                    " with username: "+nameet.getText().toString(), Toast.LENGTH_LONG).show();
            groupet.setText("");
            nameet.setText("");
        }
    }
}

private class ListenerUpdate implements View.OnClickListener {
    @Override
    public void onClick(View view) {
        getGroupInfo();
        Groupadapter = new GroupAdapter(getActivity(), R.layout.row, TCPConnection.groupsList);
        list.setAdapter(Groupadapter);
        Groupadapter.notifyDataSetChanged();
    }
}

//REVENUES list onClick LISTENER
private class listListener implements AdapterView.OnItemClickListener {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
        // ListView Clicked item index
        int itemPosition = position;
        Nameadapter.notifyDataSetChanged();

        ((MainActivity)getActivity()).getMembers(TCPConnection.groupsList.get(itemPosition).toString());
        Nameadapter.notifyDataSetChanged();

        //open selected finanse and show more information
        Dialog d = new Dialog(getActivity());
        String title = getResources().getString(R.string.dialogTitle);
        d.setTitle(title);
        d.setCanceledOnTouchOutside(true);
        //inserting xml file in Dialog
        LayoutInflater factory = LayoutInflater.from(getActivity());
        View infoLayout = factory.inflate(R.layout.dialog, null);
        memberList = (ListView) infoLayout.findViewById(R.id.memberList);
        Button updatebt = (Button) infoLayout.findViewById(R.id.updateDialogBt);
        updatebt.setOnClickListener(new updateDialogListener());
        d.setContentView(infoLayout);
        Nameadapter = new NameAdapter(getActivity(), R.layout.rownames, TCPConnection.namesList);
        memberList.setAdapter(Nameadapter);
        Nameadapter.notifyDataSetChanged();

        d.show();


    }

    private class updateDialogListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            Nameadapter = new NameAdapter(getActivity(), R.layout.rownames,                 TCPConnection.namesList);
            memberList.setAdapter(Nameadapter);
            Nameadapter.notifyDataSetChanged();
        }
    }
}
   }

这是我的错误:

 10-27 17:49:00.168  24903-24903/com.example.simon_000.buddy E/AndroidRuntime﹕ FATAL EXCEPTION: main
        Process: com.example.simon_000.buddy, PID: 24903
        java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131034141, class android.widget.ListView) with Adapter(class com.example.simon_000.buddy.customs.GroupAdapter)]
                at android.widget.ListView.layoutChildren(ListView.java:1555)
                at android.widget.AbsListView.onTouchUp(AbsListView.java:3624)
                at android.widget.AbsListView.onTouchEvent(AbsListView.java:3436)
                at android.view.View.dispatchTouchEvent(View.java:7713)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
                at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
                at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2329)
                at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1568)
                at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
                at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2277)
                at android.view.View.dispatchPointerEvent(View.java:7893)
                at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3950)
                at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3829)
                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
                at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3445)
                at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3414)
                at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3521)
                at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3422)
                at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3578)
                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
                at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3445)
                at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3414)
                at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3422)
                at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3395)
                at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5535)
                at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5515)
                at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5486)
                at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5615)
                at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
                at android.os.MessageQueue.nativePollOnce(Native Method)
                at android.os.MessageQueue.next(MessageQueue.java:138)
                at android.os.Looper.loop(Looper.java:123)
                at android.app.ActivityThread.main(ActivityThread.java:5146)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.j

1 个答案:

答案 0 :(得分:0)

必须从UI线程调用adapter.notifyDataSetChanged()。目前它是从后台线程调用的。

所以而不是:

adapter.notifyDataSetChanged();

你应该写:

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

从后台线程调用方法时。 这允许ListView使用附加到已更改的适配器的数据正确更新。