简体   繁体   English

如何从URL请求和获取jsonarray并在Android中的ListView上查看它们

[英]How to request and get jsonarray from url and view them on listview in android

Im new to android studio and I want to create an rss reader application. 我是Android Studio的新手,我想创建一个RSS阅读器应用程序。 the application should get the last news id from url,compare it to the last existing news id in the application,send a request and get json array per each id between them.and when downloading jsons were finished show them on a listview. 应用程序应从url获取最新新闻ID,将其与应用程序中现有的最新新闻ID进行比较,发送请求并获取它们之间的每个ID的json数组。下载json完成后,将其显示在列表视图中。 The problem is that I dont know how to add them to the listview. 问题是我不知道如何将它们添加到列表视图。 the MainActivity class is: MainActivity类是:

//sorry guys this class is totally messed up!
package com.example.sorush.slidr;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.example.sorush.slidr.model.NewsItems;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.r0adkll.deadskunk.adapters.BetterRecyclerAdapter;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.InjectView;


public class MainActivity extends ActionBarActivity {

@InjectView(R.id.recycler)
RecyclerView mRecycler;

private OSVersionAdapter mAdapter;
List<NewsItems> oss = null;

int i=1;
String lastidurl = api + "name=getnewsid";
String URL = api + "name=getnews" + i;
private final static  String api = "api link";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.inject(this);
    new DownloadFilesTask();

}

/**
 * Intialize Recycler
 */
private void initRecycler(){
    mAdapter = new OSVersionAdapter();
    mAdapter.addAll(getJSONFromUrl(URL));
    mRecycler.setAdapter(mAdapter);
    mRecycler.setLayoutManager(new LinearLayoutManager(this));
    mAdapter.setOnItemClickListener(new BetterRecyclerAdapter.OnItemClickListener<NewsItems>() {
        @Override
        public void onItemClick(View view, NewsItems androidOS, int i) {
            // Launch the slidable activity
            Intent viewer = new Intent(MainActivity.this, ViewerActivity.class);
            viewer.putExtra(ViewerActivity.EXTRA_OS, androidOS);
            startActivity(viewer);
        }
    });
}

private class DownloadFilesTask extends AsyncTask<String, Integer, Void> {

    @Override
    protected void onProgressUpdate(Integer... values) {
    }

    @Override
    protected void onPostExecute(Void result) {
        if (oss != null) {
            initRecycler();
        }
    }

    @Override
    protected Void doInBackground(String... params) {
        String lastid;
        lastid = getLastNewsID(lastidurl);
        int id = Integer.parseInt(lastid);

        if(lastid!=null) {
            for (i = 0; i < id ; i++) {
                 String url = params[i];
                getJSONFromUrl(url);

            }
        }else{
            //
        }
        if(i==lastid.length()){
            Intent intent = new Intent(MainActivity.this,     ViewerActivity.class);
            PendingIntent contentIntent =     PendingIntent.getActivity(MainActivity.this, 0, intent,     PendingIntent.FLAG_UPDATE_CURRENT);

            NotificationCompat.Builder b = new NotificationCompat.Builder(MainActivity.this);

            b.setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setTicker("News")
                    .setContentTitle("News Available")
                    .setContentText("news text")
                    .setDefaults(Notification.DEFAULT_LIGHTS| Notification.DEFAULT_SOUND)
                    .setContentIntent(contentIntent)
                    .setContentInfo("Info");


            NotificationManager notificationManager = (NotificationManager) MainActivity.this.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.notify(1, b.build());
        }
        return null;
    }
}
public List<NewsItems> getJSONFromUrl(String url) {
    InputStream is = null;

    // Making HTTP request
    try {

        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

        InputStreamReader isr = new InputStreamReader(is);
        Gson gson = new Gson();
        Type listType = new TypeToken<List<NewsItems>>(){}.getType();
        oss = gson.fromJson(isr, listType);

        is.close();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return oss;

}
public final static String getLastNewsID(String s){

    InputStream is = null;
    JSONObject jObj = null;
    String id = null;
    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(s);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "UTF-8"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        id = sb.toString();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return id;
  }

}

and the NewsItems class: 和NewsItems类:

package com.example.sorush.slidr.model;

import android.os.Parcel;
import android.os.Parcelable;

public class NewsItems implements Parcelable{
public String author;
public String newstitle;
public int newsid;
public String thumb;
public String date;
public String content;

public NewsItems(){}

private NewsItems(Parcel in){
    author = in.readString();
    newstitle = in.readString();
    newsid = in.readInt();
    thumb = in.readString();
    date = in.readString();
    content = in.readString();
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(author);
    dest.writeString(newstitle);
    dest.writeInt(newsid);
    dest.writeString(thumb);
    dest.writeString(date);
    dest.writeString(content);
}

public static final Creator<NewsItems> CREATOR = new Creator<NewsItems>() {
    @Override
    public NewsItems createFromParcel(Parcel source) {
        return new NewsItems(source);
    }

    @Override
    public NewsItems[] newArray(int size) {
        return new NewsItems[size];
        }
    };

}

Since you keep your NewsItems in a List, I would suggest to use ArrayAdapter for binding data with the ListView. 由于您将NewsItems保留在列表中,因此我建议使用ArrayAdapter将数据与ListView绑定。 Here is an example of an Adapter that I use. 这是我使用的适配器的示例。

public class ResultAdapter extends ArrayAdapter<Result> {
private List<Result> items;
private Context context;

static class ViewHolder {
    public ImageView icon;
    public TextView title;
    public TextView type;
}

public ResultAdapter(Context context, int resource, List<Result> objects) {
    super(context, resource, objects);
    this.context = context;
    items = objects;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // ViewHolder pattern - view stores its subviews when it's created. Next time the view is looked up it
    // reuses the views (no need to search for those again)
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.result_item, parent, false);

        ViewHolder viewHolder = new ViewHolder();
        viewHolder.icon = (ImageView) convertView.findViewById(R.id.result_item_icon);
        viewHolder.title = (TextView) convertView.findViewById(R.id.result_item_title);
        viewHolder.type = (TextView) convertView.findViewById(R.id.result_item_type);
        convertView.setTag(viewHolder);
    }
    // now the ViewHolder is prepared, next get its tag and prepare the view
    ViewHolder holder = (ViewHolder) convertView.getTag();
    Result result = items.get(position);
    holder.title.setText(result.text);
    // the Utils class is my own helper function that get me what I need from config
    holder.type.setText(Utils.getTypeString(context, result.type, true));
    holder.icon.setImageResource(Utils.getTypeSearchDrawable(result.type));
    holder.title.setTextColor(Utils.getTypeColor(context, result.type));

    return convertView;
} }

Then in your activity, set the ListView's adapter to your desired one: 然后在您的活动中,将ListView的适配器设置为所需的适配器:

ArrayList<Result> results = new ArrayList<Result>();
// fill the ArrayList results with data - you would probably get it already filled from your AsyncTask
results.add(...);
ListView list = (ListView) findViewById(R.id.result_list_view);
list.setAdapter(new ResultAdapter(this, R.id.list_item, results));

Few notes: 一些注意事项:

  • the ViewHolder pattern is not neccessary, however Eclipse warned me when I did not use it. ViewHolder模式不是必需的,但是当我不使用它时,Eclipse会警告我。 It speeds up scrolling of the ListView. 它加快了ListView的滚动。
  • you are using AsyncTask for loading the data. 您正在使用AsyncTask加载数据。 IMO, you had better to change it for AsyncTaskLoader in your activity, which will manage configuration changes for you (screen rotation etc.). IMO,最好在活动中为AsyncTaskLoader对其进行更改,这将为您管理配置更改(屏幕旋转等)。 Nice explanation of AsyncTaskLoader: http://www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html 关于AsyncTaskLoader的很好的解释: http : //www.javacodegeeks.com/2013/01/android-loaders-versus-asynctask.html

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

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