简体   繁体   中英

JSON Data is not showing, rather showing blank screen

Trying to make a simple app that will fetch JSON data from a server and show them in a custom List, pretty simple stuff.

But when I'm running the app, it is showing white blank screen but no data. It doesn't show any error either, I assume if there were any error it wouldn't be running in my phone. But doesn't show the fetched data.

Here is the MainActivity class

package com.example.root.employeedata;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONArray;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    List list  = new ArrayList<String>();
    String[] employees = new String[list.size()];
    String data = "";

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

        try{
            URL url = new URL("http://anontech.info/courses/cse491/employees.json");
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";
            while(line != null){
                line = bufferedReader.readLine();
                data = data + line;
            }

            JSONArray array = new JSONArray(data);
            for(int i=0; i<array.length(); i++){
                String employeeName = array.getJSONObject(i).getString("name");
                list.add(employeeName);
            }

            for(int i=0; i<employees.length; i++){
                employees[i] = list.get(i).toString();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }

        for(int i=0; i<employees.length; i++){
            System.out.println(employees[i]);
        }

        ListView listView = (ListView) findViewById(R.id.listView);
        CustomAdapter customAdapter = new CustomAdapter();
        listView.setAdapter(customAdapter);
    }

    class CustomAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return employees.length;
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            view = getLayoutInflater().inflate(R.layout.customlayout,null);

            TextView textView = (TextView)view.findViewById(R.id.employeeName);
            textView.setText(employees[i]);

            return view;
        }
    }
}

Here is the activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.root.employeedata.MainActivity">


    <ListView
        android:id="@+id/listView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

   </android.support.constraint.ConstraintLayout>

Here is the customlayout.xml for custom list,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/employeeName"
        android:layout_width="wrap_content"
        android:layout_height="69dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_weight="1"
        android:text="TextView" />

</RelativeLayout>

Here is the AndroidManifest.xml ,

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.root.employeedata">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission 
    android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" 
        />
            </intent-filter>
       </activity>
       </application>
  </manifest>

This is what it is showing when running the app,

在此处输入图片说明

The other questions that I have found did not match with my problem, otherwise would not be adding this question.

You're doing a network request on the MainThread . You're probably getting an exception but it's getting masked by the catch block.

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

You need to use an AsyncTask to make your network requests.

Something like this. Create an inner class:

private class GetJsonTask extends AsyncTask<URL, Void, String> {
     protected String doInBackground(URL... urls) {
         try{
            HttpURLConnection httpURLConnection = (HttpURLConnection) urls[0].openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";
            while(line != null){
                line = bufferedReader.readLine();
                data = data + line;
            }
            return data;

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

        }
        return null;
     }



     protected void onPostExecute(String result) {
         if(result!=null){
         JSONArray array = new JSONArray(result);
            for(int i=0; i<array.length(); i++){
                String employeeName = array.getJSONObject(i).getString("name");
                list.add(employeeName);
            }
         }
     }
 }

This is because your employees String array size is 0.

List list  = new ArrayList<String>();//initially it has 0 size 
String[] employees = new String[list.size()];//list.size()==0

convert employees String[] to Arraylist will solve your problem.

ArrayList<String> employees = new ArrayList<String>();

Detail See this piece of code

            for(int i=0; i<employees.length; i++){
                employees[i] = list.get(i).toString();
            }

because employees.length is 0 so your loop is basically not working even for single item.

1- Make sure your server connection logic away from UI thread, You can use something like AsyncTask .

// Make server logic inside Async Task.
    new AsyncTaskHandler(new OnFinishCallback() {
        @Override
        public void onSuccess(List<String> result) {
            CustomAdapter customAdapter = new CustomAdapter(result);
            listView.setAdapter(customAdapter);
        }
    }).execute("http://anontech.info/courses/cse491/employees.json");

2. Avoid anonymous AsyncTask memory leak static inner AsyncTask

/**
 * Static inner class to handle memory leak with inner class.
 */
public static class AsyncTaskHandler extends AsyncTask<String, Void, List<String>> {
    private final OnFinishCallback callback;
    public AsyncTaskHandler(OnFinishCallback callback) {
        this.callback = callback;
    }
.....
}

3- Update UI component ListView inside UI thread, AsyncTask method onPostExecute executed under UI thread, You can use OnFinishCallback to update list adapter after onPostExecute get called.

        @Override
        protected void onPostExecute(List<String> result) {
            // Executed under UI thread to update UI component.
            callback.onSuccess(result); 
        }

4- Use RecyclerView insteadOf ListView or at least use ViewHolder pattern Making ListView Scrolling Smooth

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            final ViewHolder viewHolder;
        .....
        }

5- Complete example.

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONArray;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ListView listView = (ListView) findViewById(R.id.listView);
        // Make server logic inside Async Task.
        new AsyncTaskHandler(new OnFinishCallback() {
            @Override
            public void onSuccess(List<String> result) {
                CustomAdapter customAdapter = new CustomAdapter(result);
                listView.setAdapter(customAdapter);
            }
        }).execute("http://anontech.info/courses/cse491/employees.json");
    }

    class CustomAdapter extends BaseAdapter {

        private final List<String> employees;

        public CustomAdapter(List<String> result) {
            this.employees = result;
        }

        @Override
        public int getCount() {
            return employees.size();
        }

        @Override
        public String getItem(int position) {
            return employees.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        // Use ViewHolder pattern.
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            final ViewHolder viewHolder;
            if (view !=null){
                viewHolder = (ViewHolder) view.getTag();
            }else {
                view = getLayoutInflater().inflate(R.layout.customlayout, null);
                viewHolder = new ViewHolder();
                viewHolder.textView = (TextView) view.findViewById(R.id.employeeName);
                view.setTag(viewHolder);
            }
            viewHolder.textView.setText(getItem(i));
            return view;
        }


        // Should use View Holder pattern
        public class ViewHolder{
            TextView textView;
        }
    }


    /**
     * Static inner class to handle memory leak with inner class.
     */
    public static class AsyncTaskHandler extends AsyncTask<String, Void, List<String>> {
        private final OnFinishCallback callback;
        public AsyncTaskHandler(OnFinishCallback callback) {
            this.callback = callback;
        }

        @Override
        protected List<String> doInBackground(String... args) {
            List<String> result = new ArrayList<>();
            try {
                URL url = new URL(args[0]);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String line = "";
                String data = "";
                while (line != null) {
                    line = bufferedReader.readLine();
                    data = data + line;
                }

                JSONArray array = new JSONArray(data);
                for (int i = 0; i < array.length(); i++) {
                    String employeeName = array.getJSONObject(i).getString("name");
                    result.add(employeeName);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }

        @Override
        protected void onPostExecute(List<String> result) {
            callback.onSuccess(result);
        }
    }

    public interface OnFinishCallback{
        void onSuccess(List<String> result);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM