繁体   English   中英

尝试从json数组生成android listview

[英]Trying to generate an android listview from a json array

所以我当前的活动类中有以下代码:

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

    bChore = (Button) findViewById(R.id.addChore);

    bChore.setOnClickListener(this);

    Bundle extras = getIntent().getExtras();
    final String user = extras.getString("username");



   fillInBackground();
}

@Override
public void onClick(View v) {

    Bundle extras = getIntent().getExtras();
    final String user = extras.getString("username");

    switch (v.getId()) {
        case R.id.addChore:
            name = (EditText) findViewById(R.id.choreName);
            value = (EditText) findViewById(R.id.points);
            String choreTitle = name.getText().toString();
            int pointValue = Integer.parseInt(value.getText().toString());
            try {
                if (choreTitle.length() <= 0)
                    Toast.makeText(Chores.this, "Please enter a chore", Toast.LENGTH_SHORT).show();
                else {
                    if (pointValue == 0)
                        Toast.makeText(Chores.this, "Please enter a valid number", Toast.LENGTH_SHORT).show();
                    else {
                        Chore chore = new Chore(choreTitle, pointValue, user);
                        uploadChore(chore);
                        break;
                    }
                }
            } catch (NumberFormatException e) {
                Toast.makeText(Chores.this, "Please enter a valid point value", Toast.LENGTH_SHORT).show();
            }
    }
}

private void fillInBackground() {


    new AsyncTask<Void, Void, Wrapper>() {


        Bundle extras = getIntent().getExtras();
        final String user = extras.getString("username");
        @Override
        protected Wrapper doInBackground(Void... params) {
            String requestURL = SERVER_ADDRESS + "FetchChoreData.php";
            ListView choreList = (ListView) findViewById(R.id.choreList);
            ArrayList<String> chores = new ArrayList<>();
            Wrapper wrapper = new Wrapper();

             String headings = "Chore" + "\t" + "Child" + "\t" + "Points";
             chores.add(headings);

            URL url;
            try {
                //Opens the connection to the PHP files
                //Sets the conditions of the connection
                url = new URL(requestURL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Opens an output stream to send the data to be verified
                // and then closes the all output streams and flushes the output writer
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));

                Uri.Builder builder = new Uri.Builder()
                        .appendQueryParameter("username", user);

                String query = builder.build().getEncodedQuery();

                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
                //saves the response code to ensure connection was succesful
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));

                //Opens an input stream to retrieve verified data back from the server
                //Starts a String Builder to read the data off the input
                //Closes the BufferedReader once it has finished building the string
                InputStream responseStream = new BufferedInputStream(conn.getInputStream());
                BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                String line;
                StringBuilder stringBuilder = new StringBuilder();
                while ((line = responseStreamReader.readLine()) != null)
                    stringBuilder.append(line + "/n");
                responseStreamReader.close();


                String response = stringBuilder.toString();
                Log.d("response", response);

                JSONObject jsonResponse = new JSONObject(response);

                //Creates a JSON object from the string

                JSONArray choresArray = jsonResponse.getJSONArray("chore");
                for (int i = 0; i < choresArray.length(); i++) {
                    JSONObject chore = choresArray.getJSONObject(i);
                    String current_chore = chore.optString("chore_name");
                    String name = chore.optString("child_username");
                    String points = chore.optString("point_value");

                    String currentChore = "";
                    if (name == null)
                        currentChore = current_chore + "\t" + "Not Claimed" + "\t" + points;
                    else
                        currentChore = current_chore + "\t" + name + "\t" + points;
                    chores.add(currentChore);
                    Log.d("Output", currentChore);

                }

                wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this,  android.R.layout.simple_list_item_1, chores);
                wrapper.list = choreList;



            } catch (Exception e) {
                e.printStackTrace();
            }
            return wrapper;
        }
        protected void onPostExecute(Wrapper wrapper) {
            //After the previous method executes we end the process dialog
            //and we return the user call back and return the verified user
            wrapper.list.setAdapter(wrapper.myArrayAdapter);
        }
    }.execute();

}




private void uploadChore(Chore chore) {
    Bundle extras = getIntent().getExtras();
    final String user = extras.getString("username");
    //Implements the ServerRequest class to register the user details
    ServerRequests serverRequests = new ServerRequests(this);
    //Checks that the details are valid and what account type it is setting up
    serverRequests.storeChoreData(chore,new GetUserCallBack() {
        //What is done when the user has successfully registered
        @Override
        public void complete(User returnedUser) {
            Intent chores = new Intent(Chores.this, Chores.class);
            chores.putExtra("username", user);
            startActivity(chores);
        }
    });
}

}

包装器类如下所示:

public class Wrapper {
     public ListView list;
     public ArrayAdapter<String> myArrayAdapter;
}

但是,当我运行该应用程序时,它停止了,并且出现以下致命异常:

W/System.err: org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err:     at org.json.JSON.typeMismatch(JSON.java:111)
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:160)
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:173)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at com.jack.pointcollector.Chores$1.doInBackground(Chores.java:149)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at com.jack.pointcollector.Chores$1.doInBackground(Chores.java:89)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:295)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err:     at java.lang.Thread.run(Thread.java:818)
03-14 11:54:17.581 18935-18935/com.jack.pointcollector D/AndroidRuntime: Shutting down VM
03-14 11:54:17.581 18935-18935/com.jack.pointcollector E/AndroidRuntime: FATAL EXCEPTION: main Process: com.jack.pointcollector, PID: 18935
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at     com.jack.pointcollector.Chores$1.onPostExecute(Chores.java:183)
at     com.jack.pointcollector.Chores$1.onPostExecute(Chores.java:89)
at     android.os.AsyncTask.finish(AsyncTask.java:651)
at     android.os.AsyncTask.-wrap1(AsyncTask.java)
at     android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at     android.os.Handler.dispatchMessage(Handler.java:102)
at     android.os.Looper.loop(Looper.java:148)
at     android.app.ActivityThread.main(ActivityThread.java:5417)
at     java.lang.reflect.Method.invoke(Native Method)
at     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at     com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

有人可以告诉我我要去哪里了,因为我只是新来的。

问题仅在于您在doInBackgroud()方法中创建了对象包装........并且您尝试在onPostExecute()方法中进行访问....

        new AsyncTask<Void, Void, Wrapper>() {



            @Override
            protected Wrapper doInBackground(Void... params) {

                ListView choreList = (ListView) findViewById(R.id.choreList);
                ArrayList<String> chores = new ArrayList<>();

               // change this make them Global.....
                Wrapper wrapper = new Wrapper();


                    wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this,  android.R.layout.simple_list_item_1, chores);
                    wrapper.list = choreList;



                } catch (Exception e) {
                    e.printStackTrace();
                }
                return wrapper;
            }
            protected void onPostExecute(Wrapper wrapper) {
                //After the previous method executes we end the process dialog
                //and we return the user call back and return the verified user
                wrapper.list.setAdapter(wrapper.myArrayAdapter);
            }
        }.execute();

    }

你应该搬家

     ListView choreList = (ListView) findViewById(R.id.choreList);
        ArrayList<String> chores = new ArrayList<>();

在后台执行操作,并将其作为全局变量。

提取完数据后,可以在onPost execute中设置适配器。 您的列表视图永远不会初始化,因此会出现空指针异常。

以下是我在您的代码中发现的错误,并且我也尝试修复该错误。

您应该在onCreate()初始化所有视图和适配器。

uploadChore()complete() ,不要为将数据传递给其他方法而启动相同的活动,而uploadChore()其作为参数传递。

ListView及其Adapter应在开始时进行初始化。 稍后,将数据添加到列表中并调用适配器的notifyDataSetChanged()

ArrayList<String> chores;
Wrapper wrapper;

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

    bChore = (Button) findViewById(R.id.addChore);
    name = (EditText) findViewById(R.id.choreName);
    value = (EditText) findViewById(R.id.points);

    wrapper = new Wrapper();
    ListView choreList = (ListView) findViewById(R.id.choreList);
    chores = new ArrayList<>();
    wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this, android.R.layout.simple_list_item_1, chores);
    wrapper.list = choreList;
    wrapper.list.setAdapter(wrapper.myArrayAdapter);

    bChore.setOnClickListener(this);

}

@Override
public void onClick(View v)
{
    Bundle extras = getIntent().getExtras();
    final String user = extras.getString("username");

    switch (v.getId())
    {
        case R.id.addChore:

            String choreTitle = name.getText().toString();
            int pointValue = Integer.parseInt(value.getText().toString());
            try
            {
                if (choreTitle.length() <= 0)
                    Toast.makeText(Chores.this, "Please enter a chore", Toast.LENGTH_SHORT).show();
                else
                {
                    if (pointValue == 0)
                        Toast.makeText(Chores.this, "Please enter a valid number", Toast.LENGTH_SHORT).show();
                    else
                    {
                        Chore chore = new Chore(choreTitle, pointValue, user);
                        uploadChore(chore);
                        break;
                    }
                }
            }
            catch (NumberFormatException e)
            {
                Toast.makeText(Chores.this, "Please enter a valid point value", Toast.LENGTH_SHORT).show();
            }
    }
}

private void fillInBackground(String user)
{
    new AsyncTask<Void, String, Wrapper>()
    {

        @Override
        protected Wrapper doInBackground(Void... params)
        {
            String requestURL = SERVER_ADDRESS + "FetchChoreData.php";


            String headings = "Chore" + "\t" + "Child" + "\t" + "Points";
            publishProgress(headings);

            URL url;
            try
            {
                //Opens the connection to the PHP files
                //Sets the conditions of the connection
                url = new URL(requestURL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Opens an output stream to send the data to be verified
                // and then closes the all output streams and flushes the output writer
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));

                Uri.Builder builder = new Uri.Builder()
                        .appendQueryParameter("username", user);

                String query = builder.build().getEncodedQuery();

                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
                //saves the response code to ensure connection was succesful
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));

                //Opens an input stream to retrieve verified data back from the server
                //Starts a String Builder to read the data off the input
                //Closes the BufferedReader once it has finished building the string
                InputStream responseStream = new BufferedInputStream(conn.getInputStream());
                BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                String line;
                StringBuilder stringBuilder = new StringBuilder();
                while ((line = responseStreamReader.readLine()) != null)
                    stringBuilder.append(line + "/n");
                responseStreamReader.close();


                String response = stringBuilder.toString();
                Log.d("response", response);

                JSONObject jsonResponse = new JSONObject(response);

                //Creates a JSON object from the string

                JSONArray choresArray = jsonResponse.getJSONArray("chore");
                for (int i = 0; i < choresArray.length(); i++)
                {
                    JSONObject chore = choresArray.getJSONObject(i);
                    String current_chore = chore.optString("chore_name");
                    String name = chore.optString("child_username");
                    String points = chore.optString("point_value");

                    String currentChore = "";
                    if (name == null)
                        currentChore = current_chore + "\t" + "Not Claimed" + "\t" + points;
                    else
                        currentChore = current_chore + "\t" + name + "\t" + points;
                    publishProgress(currentChore);
                    Log.d("Output", currentChore);

                }

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

        @Override
        protected void onProgressUpdate(String... values)
        {
            super.onProgressUpdate(values);
            wrapper.list.add(values[0]);
        }

        protected void onPostExecute(Wrapper wrapper)
        {
            //After the previous method executes we end the process dialog
            //and we return the user call back and return the verified user
            wrapper.myArrayAdapter.notifyDataSetChanged();
        }
    }.execute();

}

private void uploadChore(Chore chore)
{
    Bundle extras = getIntent().getExtras();
    final String user = extras.getString("username");
    //Implements the ServerRequest class to register the user details
    ServerRequests serverRequests = new ServerRequests(this);
    //Checks that the details are valid and what account type it is setting up
    serverRequests.storeChoreData(chore, new GetUserCallBack()
    {
        //What is done when the user has successfully registered
        @Override
        public void complete(User returnedUser)
        {
            // Simple add data into the list. Don't start same activity again and again.
            fillInBackground(user);
        }
    });
}

字符串响应= stringBuilder.toString(); JSONObject jsonResponse =新的JSONObject(response);

检查响应应该像这样:{“ chore”:[{“ chore_name”:“ name”,“ child_username”:“ username”,“ point_value”:“ value”},{“ chore_name”:“ name”,“ child_username “:”用户名“,” point_value“:”值“}]}

原因:

问题不在于设置适配器,而在于JSON解析。 根据您的错误日志

W/System.err: org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject

您将获得无法转换为JSONObject字符串。 发生此错误时,此时将在catch块中捕获该错误

wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this,  android.R.layout.simple_list_item_1, chores);
wrapper.list = choreList;

不被调用。 这导致onPostExecute接收到listview的空对象,并最终引发NPE

解:

您应该检查从表单服务器获取的JSON并更正它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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