Android AsyncTask ListView – JSON

很多时候,我们需要使用AsyncTask填充Listview 。 当我们必须调用远程服务器并使用JSON交换信息时,就是这种情况。

在这篇文章中,我想更深入地研究ListView 。 在之前的文章中,我描述了如何使用标准和自定义适配器以几种方式使用ListView。 在所有示例中,我应该设置一个固定的项目。 在这篇文章中,我将描述如何直接从JEE Server检索项目。

为了简单起见,假设我们有一个简单的JEE服务器来管理某些联系人。 我们的联系方式是:姓名,姓氏,电子邮件和电话号码。 如何使这台服务器超出了本文的范围,我将仅提供源代码。 为了给您提供一些细节,我可以说该服务器是使用RESTFul Web服务(在我们的情况下是jersey API)开发的JEE服务器。

在这种情况下,该应用程序的行为类似于客户端,该客户端调用remove服务以获取联系人列表并使用ListView对其进行显示。 从服务器传递到客户端的数据使用JSON格式化。

与往常一样,我们开始创建使用自定义布局的自定义适配器。 如果您需要有关创建自定义适配器的更多信息,可以在这里这里看看。 这是代码:

public class SimpleAdapter extends ArrayAdapter<Contact> {

    private List<Contact> itemList;
    private Context context;

    public SimpleAdapter(List<Contact> itemList, Context ctx) {
        super(ctx, android.R.layout.simple_list_item_1, itemList);
        this.itemList = itemList;
        this.context = ctx;        
    }

    public int getCount() {
        if (itemList != null)
            return itemList.size();
        return 0;
    }

    public Contact getItem(int position) {
        if (itemList != null)
            return itemList.get(position);
        return null;
    }

    public long getItemId(int position) {
        if (itemList != null)
            return itemList.get(position).hashCode();
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v = convertView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.list_item, null);
        }

        Contact c = itemList.get(position);
        TextView text = (TextView) v.findViewById(R.id.name);
        text.setText(c.getName());

        TextView text1 = (TextView) v.findViewById(R.id.surname);
        text1.setText(c.getSurname());

        TextView text2 = (TextView) v.findViewById(R.id.email);
        text2.setText(c.getEmail());

        TextView text3 = (TextView) v.findViewById(R.id.phone);
        text3.setText(c.getPhoneNum());

        return v;

    }

    public List<Contact> getItemList() {
        return itemList;
    }

    public void setItemList(List<Contact> itemList) {
        this.itemList = itemList;
    }

}

到现在为止,一切都变得顺畅而轻松。

HTTP客户端

我们需要做的一件事就是创建我们的HTTP客户端,以便向JEE服务器发出请求。 众所周知,HTTP请求可能需要很长时间才能提供答案,因此我们需要将此帐户考虑在内,以便Android OS不会停止我们的应用程序。 最简单的操作是创建一个AsyncTask ,该AsyncTask发出此请求并等待响应。

private class AsyncListViewLoader extends AsyncTask<String, Void, List<Contact>> {
    private final ProgressDialog dialog = new ProgressDialog(MainActivity.this);

    @Override
    protected void onPostExecute(List<Contact> result) {            
        super.onPostExecute(result);
        dialog.dismiss();
        adpt.setItemList(result);
        adpt.notifyDataSetChanged();
    }

    @Override
    protected void onPreExecute() {        
        super.onPreExecute();
        dialog.setMessage("Downloading contacts...");
        dialog.show();            
    }

    @Override
    protected List<Contact> doInBackground(String... params) {
        List<Contact> result = new ArrayList<Contact>();

        try {
            URL u = new URL(params[0]);

            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setRequestMethod("GET");

            conn.connect();
            InputStream is = conn.getInputStream();

            // Read the stream
            byte[] b = new byte[1024];
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            while ( is.read(b) != -1)
                baos.write(b);

            String JSONResp = new String(baos.toByteArray());

            JSONArray arr = new JSONArray(JSONResp);
            for (int i=0; i < arr.length(); i++) {
                result.add(convertContact(arr.getJSONObject(i)));
            }

            return result;
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
        return null;
    }

    private Contact convertContact(JSONObject obj) throws JSONException {
        String name = obj.getString("name");
        String surname = obj.getString("surname");
        String email = obj.getString("email");
        String phoneNum = obj.getString("phoneNum");

        return new Contact(name, surname, email, phoneNum);
    }

}

让我们分析一下代码。

在任务开始之前的第一步( onPreExecute() )中,我们仅显示一个对话框以通知用户该应用程序正在下载联系人列表。 最有趣的部分是应用程序建立HTTP连接的doInBackground方法。 我们首先创建一个HTTPConnection,然后像这样设置GET方法:

HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod("GET");

conn.connect();

接下来,我们创建一个输入流,然后读取字节流:

InputStream is = conn.getInputStream();
 // Read the stream
 byte[] b = new byte[1024];
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 while ( is.read(b) != -1)
    baos.write(b);

现在我们将所有流都保存在字节数组中,我们只需要使用JSON对其进行解析。

JSONArray arr = new JSONArray(JSONResp);
for (int i=0; i < arr.length(); i++) {
    result.add(convertContact(arr.getJSONObject(i)));
}

return result;

做完了! 接下来是什么?…我们需要通知适配器我们有一个新的联系人列表,并且必须显示它。 我们可以在onPostExecute(List <Contact> result)中做到这一点:

super.onPostExecute(result);
dialog.dismiss();
adpt.setItemList(result);
adpt.notifyDataSetChanged();

参考: Android AsyncTask ListView –来自我们JCG合作伙伴 Francesco Azzola的JSON,来自Surviving w / Android博客。

翻译自: https://www.javacodegeeks.com/2013/06/android-asynctask-listview-json.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值