0

In my main activity (LocalFeed) I have a listview that is connected to an AsyncTask which gets data from the database in Json format and then it sends it to the BaseAdapter. My problem is that notifyDataSetChanged() does nothing for me (upon further researching I got the logcat output from it included below), I have read a lot of posts on here like this one Android notifyDataSetChanged not working and have implemented their idea's but nothing works. I get the data originally when I set the adapter but when I have new data coming in it stays the same unless I call setAdapter again which is bad practice. First this is my activity..

public class LocalFeed extends Activity
{

 String localstreams;
EditText POST;
SharedPreferences myaccount,mya;

 String PathUrl;
 float tlatmin,tlatmax,tlonmin,tlonmax,latitudes,longitudes;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.local_feed);


  // Inputs that are used for the database
    PathUrl = getResources().getString(R.string.PathUrl);
    // URL for data api
    localstreams = PathUrl + "/api/streams";
    tlatmin = myaccount.getFloat("thirtylatmin", 0.0f);
    tlatmax = myaccount.getFloat("thirtylatmax", 0.0f);
    tlonmin = myaccount.getFloat("thirtylonmin", 0.0f);
    tlonmax = myaccount.getFloat("thirtylonmax", 0.0f);
    latitudes = myaccount.getFloat("latitudes", 0.0f);
    longitudes = myaccount.getFloat("longitudes", 0.0f);


    // This is the AsyncTask that will get the Json Data from the database
final ListView lv = (ListView) findViewById(R.id.localfeed);
    new Streams_Async(localstreams, tlatmin, tlatmax, tlonmin, tlonmax, LocalFeed.this, myaccount, 1,lv).execute();

    // I would like to setAdapter here but Json data only comes after onPostexecute of AsyncTask

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater mif=getMenuInflater();
    mif.inflate(R.menu.menu_local_feed, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();


    if (id == R.id.Logout) {

        SharedPreferences settings = getSharedPreferences("userInfo", MODE_PRIVATE);
        settings.edit().clear().commit();
      startActivity(new Intent(LocalFeed.this,Login.class));

        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

I pass my Listview To the AsyncTask() since the data comes from there I can not call adapter until the onPostExecute() method. This is my AsyncTask()

public class Streams_Async extends AsyncTask<String,String,String> {
        HttpURLConnection conn;
        URL url;
        String result="";
        DataOutputStream wr;
       String Stream_URL;
        Activity m;
       Integer page;
    float tlatmin,tlatmax,tlonmin,tlonmax;
    SharedPreferences myaccount;


    public Streams_Async(String Stream_URL,float tlatmin,float tlatmax,float tlonmin,float tlonmax,Activity m,SharedPreferences myaccount,Integer page)
    {
        this.Stream_URL=Stream_URL;
        this.tlatmin=tlatmin;
        this.tlatmax=tlatmax;
        this.tlonmin=tlonmin;
        this.tlonmax=tlonmax;
        this.m=m;
        this.myaccount=myaccount;
        this.page=page;
    }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... params) {

// All This does it just get the data from the database
            BufferedReader reader=null;
            try{
                url = new URL(Stream_URL);
                conn = (HttpURLConnection) url.openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                conn.connect();

                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);


                String cert="thirtylatmin="+myaccount.getFloat("thirtylatmin", 0)+"&thirtylatmax="+myaccount.getFloat("thirtylatmax", 0)+"&thirtylonmin="+myaccount.getFloat("thirtylonmin", 0)+"&thirtylonmax="+myaccount.getFloat("thirtylonmax", 0)+
                        "&page="+page+"&pid="+myaccount.getInt("id", 0);


                wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(cert);
                wr.flush();
                wr.close();

                reader =  new BufferedReader(new InputStreamReader(conn.getInputStream()));
                StringBuilder sBuilder = new StringBuilder();

                String line = "";
                while ((line = reader.readLine()) != null) {
                    sBuilder.append(line + "\n");
                }


                result = sBuilder.toString();
                reader.close();
                conn.disconnect();
                return result;



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

            return result;

        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
     // All the data needed for listview is in result variable
            try {

                JSONObject jsonn = new JSONObject(result);

                JSONArray jArray = jsonn.getJSONArray("localstreams");
                JSONObject jobject = null;
                JSONArray sss = new JSONArray();
                for (int i = 0; i < jArray.length(); i++) {
                    jobject = jArray.getJSONObject(i);
                    jobject.getString("post");
                    jobject.getString("fullname");
                    jobject.getInt("id");
                    jobject.getInt("myid");
                    jobject.getInt("reputation");
                    jobject.getString("city");
                    jobject.getString("last_reply");
                    jobject.getString("state");
                    sss.put(jobject);
                }

                jsonn.put("localstreams", sss);

   System.err.println("nnn: " + result);
       if (lv.getAdapter() == null)
        {
      ListView mm= (ListView) m.findViewById(R.id.localfeed);
            LocalFeed_CustomView DMF = new LocalFeed_CustomView(jsonn, m);
           mm.setAdapter(DMF);

    }
        else
        {
            // This right here does not work
            LocalFeed_CustomView DMF = new LocalFeed_CustomView(jsonn, m);
            DMF.notifyDataSetChanged();

        }

            }
            catch (Exception e) {
          System.err.println("pp"+e.getMessage());
            }

        }
    }

As you can see my problem is in the else statement inside onPostExecute it does not work; the **DMF.notifyDataSetChanged();**results in a parsing error which I can not find how to overcome.

public class LocalFeed_CustomView extends BaseAdapter {

    JSONObject names;
    Context ctx;
   //,ra;
    String result="";
    private LayoutInflater mLayoutInflater = null;
    public  LocalFeed_CustomView(){}


    public LocalFeed_CustomView(JSONObject arr,Context c) {
        ctx = c;
        names = arr;
        mLayoutInflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        notifyDataSetChanged();

    }

    public void updateList(){
    notifyDataSetChanged();
}


    @Override
    public int getCount() {
        try {
            JSONArray jaLocalstreams = names.getJSONArray("localstreams");
            return jaLocalstreams.length();
        } catch (Exception e) {
            Toast.makeText(ctx,"Error: Please try again",Toast.LENGTH_LONG).show();
            return names.length();
        }


    }




    @Override
    public Object getItem(int position) {

        return position;
    }

    @Override
    public long getItemId(int position) {

        return position;
    }

    @Override
    public View getView(int position,View convertView, ViewGroup parent) {
        View row=convertView;
        MyViewHolder holder=null;
        try {

            if(row==null) {
             LayoutInflater li= (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = li.inflate(R.layout.customadapter, parent, false);

                holder=new MyViewHolder(row);
                row.setTag(holder);
            }
else
            {

                holder=(MyViewHolder)row.getTag();

            }
        updateList();

            // This populates Listview

            JSONArray jaLocalstreams = names.getJSONArray("localstreams");
            System.err.println("ssd:" + names);
            final JSONObject jsonObject = jaLocalstreams.getJSONObject(position);
            int a=  jsonObject.getInt("myid");

            holder.post.setText(jsonObject.getString("post"));
            holder.fullname.setText(jsonObject.getString("fullname"));
            holder.city.setText(jsonObject.getString("city")+ ", ");
            holder.state.setText(jsonObject.getString("state"));
            holder.comments.setText(jsonObject.getInt("comments")+ " Comments ");
            holder.last_reply.setText(jsonObject.getString("last_reply"));
            holder.reputation.setText(jsonObject.getString("reputation"));
            jsonObject.getInt("profile_id");
            jsonObject.getInt("id");

            SharedPreferences myaccount = ctx.getSharedPreferences("userInfo", MODE_PRIVATE);
            int my_id = myaccount.getInt("id", 0);

            return row;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return row;


    }

     class MyViewHolder{
        TextView post,fullname,city,state,last_reply,comments,reputation;
         ImageButton reputation_add;

         MyViewHolder(View v)
         {
          post= (TextView)v.findViewById(R.id.post);
             fullname= (TextView)v.findViewById(R.id.fullname);
             city= (TextView)v.findViewById(R.id.city);
             state= (TextView)v.findViewById(R.id.state);
         last_reply= (TextView)v.findViewById(R.id.last_reply);
        comments = (TextView)v.findViewById(R.id.id);
         reputation= (TextView)v.findViewById(R.id.reputation);
           reputation_add= (ImageButton)v.findViewById(R.id.reputation_add);
         }



    }

}

This below is the problem area

 else
    {
        // This right here does not work
        LocalFeed_CustomView DMF = new LocalFeed_CustomView(jsonn, m);
        DMF.notifyDataSetChanged();

    }

It goes to the catch statement and it's cause is null, this is the logcat for it.. What in my else code could be causing this error

java.lang.IllegalStateException: problem parsing idx 1
            at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:300)
            at com.android.server.NetworkManagementService.getNetworkStatsUidDetail(NetworkManagementService.java:1282)
            at com.android.server.net.NetworkStatsService.performPollLocked(NetworkStatsService.java:831)
            at com.android.server.net.NetworkStatsService.updateIfacesLocked(NetworkStatsService.java:743)
            at com.android.server.net.NetworkStatsService.updateIfaces(NetworkStatsService.java:721)
            at com.android.server.net.NetworkStatsService.access$000(NetworkStatsService.java:128)
            at com.android.server.net.NetworkStatsService$1.onReceive(NetworkStatsService.java:612)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
     Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)
            at libcore.io.IoBridge.open(IoBridge.java:406)
            at java.io.FileInputStream.<init>(FileInputStream.java:78)
            at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:269)
            at com.android.server.NetworkManagementService.getNetworkStatsUidDetail(NetworkManagementService.java:1282)
            at com.android.server.net.NetworkStatsService.performPollLocked(NetworkStatsService.java:831)
            at com.android.server.net.NetworkStatsService.updateIfacesLocked(NetworkStatsService.java:743)
            at com.android.server.net.NetworkStatsService.updateIfaces(NetworkStatsService.java:721)
            at com.android.server.net.NetworkStatsService.access$000(NetworkStatsService.java:128)
            at com.android.server.net.NetworkStatsService$1.onReceive(NetworkStatsService.java:612)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
     Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
            at libcore.io.Posix.open(Native Method)
            at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
            at libcore.io.IoBridge.open(IoBridge.java:390)
            at java.io.FileInputStream.<init>(FileInputStream.java:78)
            at com.android.internal.net.NetworkStatsFactory.readNetworkStatsDetail(NetworkStatsFactory.java:269)
            at com.android.server.NetworkManagementService.getNetworkStatsUidDetail(NetworkManagementService.java:1282)
            at com.android.server.net.NetworkStatsService.performPollLocked(NetworkStatsService.java:831)
            at com.android.server.net.NetworkStatsService.updateIfacesLocked(NetworkStatsService.java:743)
            at com.android.server.net.NetworkStatsService.updateIfaces(NetworkStatsService.java:721)
            at com.android.server.net.NetworkStatsService.access$000(NetworkStatsService.java:128)
            at com.android.server.net.NetworkStatsService$1.onReceive(NetworkStatsService.java:612)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.os.HandlerThread.run(HandlerThread.java:60)
09-30 03:47:45.001        36-67/? E/SurfaceTexture﹕ [com.exoler/com.exoler.Login] drainQueueLocked: SurfaceTexture has been abandoned!
09-30 03:47:45.261      158-188/com.android.inputmethod.latin E/ActivityThread﹕ Failed to find provider info for com.android.inputmethod.latin.dictionarypack
09-30 03:47:45.271      158-188/com.android.inputmethod.latin E/BinaryDictionaryGetter﹕ Could not find a dictionary pack
Community
  • 1
  • 1
Ignacio Perez
  • 2,341
  • 3
  • 13
  • 18
  • See: http://stackoverflow.com/questions/31014229/android-httpurlconnection-not-posting-to-url – logcat Sep 30 '15 at 04:49

1 Answers1

1

If your list already has an adapter, perhaps you don't need to recreate one, but instead get the adapter from the list, set fresh data to it (consider synchronization here, as another thread may try to access some of the data just when you're changing it) and then call notifyDataSetChanged():

else {
    LocalFeed_CustomView DMF = (LocalFeed_CustomView) lv.getAdapter();
    synchronized (namesLock) {
        DMF.names = ...
    }
    DMF.notifyDataSetChanged();
}

In contrast, you create a new, unassigned, adapter and then simply call notifyDataSetChanged() on it. But it wasn't yet added to any list, which may cause the problem. Anyway, in your case, obviously you want to refer to the already existing adapter and update the list that's already shown to the screen.

logcat
  • 283
  • 2
  • 12
  • Yes Synchronization sounds right because once we get into the else statement it means that there is an adapter already and the new Jsonn data is meant to add to what is already there. I will try now the example you have above. What is the namesLock? – Ignacio Perez Sep 30 '15 at 05:27
  • Hi again. The namesLock is just an Object (public Object namesLock = new Object()) that you define as a GLOBAL variable for use as a lock (mutex in C, if you know) and with which you perform the synchronization. It's like a key that any thread who wants to perform an operation must possess before it can do something. Once the lock is defined, you should surround any attempt to read / modify the names data structure throughout the app with a synchronized (namesLock) {} block. – logcat Sep 30 '15 at 18:57
  • The most important thing in my answer, I think, is that you should use the already existing adapter instead of creating a new, unrelated one. – logcat Sep 30 '15 at 19:00