0

我一直在开发一个使用 JSON 解析器从数据库中提取数据并将其显示在 ListView 中的应用程序。它基于此处示例的代码。LoadAllProducts我的问题是,当创建主视图时,ListView 由一个名为.

LoadAllProductsonCreate简单地new LoadAllProducts().execute();调用,但是如果我从一个按钮调用同一行,onClick它所做的只是显示加载对话框,实际上并没有做任何事情。

完整代码如下。

package com.mystraldesign.aggregate;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ActionBar;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.net.Uri;
import android.widget.Toast;

import java.util.Date;
import java.text.SimpleDateFormat;

import com.mystraldesign.aggregate.JSONParser;

public class MainActivity extends ListActivity
{

    // Progress Dialog
    private ProgressDialog pDialog;

    // Creating JSON Parser object
    JSONParser jParser = new JSONParser();

    ArrayList<HashMap<String, Object>> articlesList;

    // url to get all articles list
    private static String url_all_articles = "http://10.13.23.211/aggregate/api.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_PRODUCTS = "articles";
    private static final String TAG_BODY = "body";
    private static final String TAG_TITLE = "title";
    private static final String TAG_URL = "url";
    private static final String TAG_TIME = "postdate";
    private static final String TAG_SITE = "site";


    // products JSONArray
    JSONArray products = null;

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



        // Hashmap for ListView
        articlesList = new ArrayList<HashMap<String, Object>>();

        // Loading products in Background Thread
        new LoadAllProducts().execute();

        // Get listview
        ListView lv = getListView();

        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                // getting values from selected ListItem
                String pid = ((TextView) view.findViewById(R.id.url)).getText()
                        .toString();

                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(pid));
                startActivity(i);
                // sending pid to next activity
                Intent in;


            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_refresh:
                Toast.makeText(this, "Menu Item 1 selected", Toast.LENGTH_SHORT)
                        .show();
                new LoadAllProducts().execute();
                // Loading products in Background Thread





                break;
            case R.id.action_copy:
                Toast.makeText(this, "Menu item 2 selected", Toast.LENGTH_SHORT)
                        .show();
                break;

            default:
                break;
        }

        return true;
    }

    public void onPause()
    {
        super.onPause();
        if(pDialog != null)
            pDialog.dismiss();
    }

    public void reloadArticles(View view)
    {
        new LoadAllProducts().execute();
    }




    /**
     * Background Async Task to Load all product by making HTTP Request
     * */
    class LoadAllProducts extends AsyncTask<String, String, String>
    {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Loading Articles. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }

        /**
         * getting All products from url
         * */
        protected String doInBackground(String... args) {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();

            // getting JSON string from URL
            JSONObject json = jParser.makeHttpRequest(url_all_articles, "GET", params);

            // Check your log cat for JSON reponse
            Log.d("All Articles: ", json.toString());

            try {
                // Checking for SUCCESS TAG
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // products found
                    // Getting Array of Products
                    products = json.getJSONArray(TAG_PRODUCTS);

                    // looping through All Products
                    for (int i = 0; i < products.length(); i++) {
                        JSONObject c = products.getJSONObject(i);

                        // Storing each json item in variable
                        String id = c.getString(TAG_BODY);
                        String name = c.getString(TAG_TITLE);
                        String uri = c.getString(TAG_URL);
                        Long timestamp = c.getLong(TAG_TIME);
                        String site = c.getString(TAG_SITE);

                        timestamp = timestamp * 1000;
                        Date date = new Date(timestamp);
                        String dateFormated;

                        SimpleDateFormat formatForDate = new SimpleDateFormat("EEE, MMM d K:mm a");
                        StringBuilder convertedDate = new StringBuilder(formatForDate.format(date));
                        dateFormated = convertedDate.toString();

                        //Used to store Image ID for setting Image in ListView
                        int iID = 0;

                        //Find out the SITE name and set Image from Drawable Accordingly
                        if(site.equals("nyt"))
                        {
                            iID = R.drawable.nyt;
                        }
                        else if(site.equals("bbc"))
                        {
                            iID = R.drawable.bbc;
                        }
                        else if(site.equals("dm"))
                        {
                            iID = R.drawable.dm;
                        }
                        else if(site.equals("reuters"))
                        {
                            iID = R.drawable.reuters;
                        }

                        // creating new HashMap
                        HashMap<String, Object> map = new HashMap<String, Object>();

                        // adding each child node to HashMap key => value
                        map.put(TAG_BODY, id);
                        map.put(TAG_TITLE, name);
                        map.put(TAG_URL, uri);
                        map.put(TAG_TIME, dateFormated);
                        map.put(TAG_SITE, iID);


                        // adding HashList to ArrayList
                        articlesList.add(map);
                    }
                } else {

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

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after getting all products
            pDialog.dismiss();
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
                    /**
                     * Updating parsed JSON data into ListView
                     * */


                     ListAdapter adapter;
                    adapter = new SimpleAdapter(
                           MainActivity.this, articlesList,
                           R.layout.list_row, new String[] { TAG_BODY, TAG_TITLE, TAG_URL, TAG_TIME, TAG_SITE},
                           new int[] { R.id.id, R.id.headline, R.id.url, R.id.time, R.id.list_i});
                    // updating listview
                    setListAdapter(adapter);
                }
            });

        }

    }
}
4

2 回答 2

2

尝试这个:

1.onPostExecute它的UI线程

onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给该步骤。

2.NotifyDatachanged 调用

setListAdapter(adapter);
//Here call notifydatasetchanged

3.尽量不要重新创建适配器,创建一次,然后只调用 clear() 清除项目,然后添加新的。还有notifydatasetchanged它的

通知附加的观察者底层数据已更改,任何反映数据集的视图都应自行刷新。

于 2013-06-07T12:31:02.823 回答
1

更好的方式与适当的内存处理。

参数:

ArrayList<HashMap<String, Object>> articlesList;
SimpleAdapter mAdapter;
LoadAllProducts mLoader;

创建对象:

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



    // Hashmap for ListView
    articlesList = new ArrayList<HashMap<String, Object>>();

    // Loading products in Background Thread
    mLoader = new LoadAllProducts();

    // Get listview
    ListView lv = getListView();

    lv.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            // getting values from selected ListItem
            String pid = ((TextView) view.findViewById(R.id.url)).getText()
                    .toString();

            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setData(Uri.parse(pid));
            startActivity(i);
            // sending pid to next activity
            Intent in;


        }
    });

    mAdapter = new SimpleAdapter(
           MainActivity.this, articlesList,
           R.layout.list_row, new String[] { TAG_BODY, TAG_TITLE, TAG_URL, TAG_TIME, TAG_SITE},
           new int[] { R.id.id, R.id.headline, R.id.url, R.id.time, R.id.list_i}); // empty list will be;
    setListAdapter(mAdapter);

    mLoader.execute();

更新按钮:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_refresh:
            Toast.makeText(this, "Menu Item 1 selected", Toast.LENGTH_SHORT)
                    .show();
            mLoader.execute();
            break;
        case R.id.action_copy:
            Toast.makeText(this, "Menu item 2 selected", Toast.LENGTH_SHORT)
                    .show();
            break;
    }
    return true;
}

不需要“reloadArticles”方法,或者只是用 mLoader.execute() 替换它们的主体;

然后从现有列表中删除数据(以预测数据重复):

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mAdapter.clear();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Loading Articles. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

并用新数据填充适配器:

    protected void onPostExecute(String file_url) {
        // dismiss the dialog after getting all products
        pDialog.dismiss();
        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {
                /**
                 * Updating parsed JSON data into ListView
                 * */

                // updating listview
                mAdapter.notifyDataSetChanged();
            }
        });
    }
于 2013-06-07T12:38:50.547 回答