试图在recyclerview中获取json但没有成功

时间:2018-02-06 11:29:54

标签: android android-asynctask android-recyclerview

以前我使用过ArrayAdapter和列表视图,所以我做了这段代码来更新UI。

private class UserAsync extends AsyncTask<String,Void,List<User>>{

    @Override
    protected List<User> doInBackground(String... urls) {

        if(urls.length <1 || urls[0] == null){
            return null;
        }

        List<User> result = null;
        try {
            result = QueryUtils.fetchJson(urls[0]);
        } catch (JSONException e) {
            Log.e(LOG_TAG,"Error in fetching json",e);
        }

        return result;
    }

    @Override
    protected void onPostExecute(List<User> users) {
        // Clear the adapter of previous earthquake data
        mAdapter.clear();

        // If there is a valid list of {@link user}s, then add them to the adapter's
        // data set. This will trigger the ListView to update.

        if(users != null && !users.isEmpty()){
            mAdapter.addAll(users);
            // After adding user to the adapter, Notify adapter for UI update
            mAdapter.notifyDataSetChanged();
        }
    }
}

现在我已尝试RecyclerViewCardView来获取数据,但上述代码不适用于recyclerview ..

我想知道如何为回收商视图实施doInBackgroundonPostExecute

activity_main.xml中

<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="examle.android.com.recyclerviewnetwork.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

items.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:elevation="8dp"
    app:cardCornerRadius="5dp"
    android:layout_marginTop="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:padding="25dp">

        <LinearLayout

            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">
        <ImageView
            android:id="@+id/avatar"
            android:layout_width="108dp"
            android:layout_height="108dp"
            android:padding="15dp"
            tools:src="@mipmap/ic_launcher" />
            <LinearLayout
                android:paddingRight="15dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">


            <TextView
                android:id="@+id/login"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingTop="15dp"
                tools:text="LOGIN_USER" />
            <TextView
                android:id="@+id/type"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingTop="3dp"
                tools:text="USER_TYPE" />
            </LinearLayout>
        </LinearLayout>
    </android.support.v7.widget.CardView>

Main_activity.java

public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    UserAdapter mAdapter;
    RecyclerView.LayoutManager layoutManager;
    private static final String JSON_URL = "https://api.github.com/users";
    private static final String LOG_TAG = MainActivity.class.getSimpleName();

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

        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        mAdapter = new UserAdapter(new ArrayList<User>(),this);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(mAdapter);

        UserAsyncTask task = new UserAsyncTask();
        task.execute(JSON_URL);
    }

    public class UserAsyncTask extends AsyncTask<String, Void, List<User>>{
        @Override
        protected List<User> doInBackground(String... urls) {

            if(urls.length < 1 || urls[0] == null ){
                return null;
            }

            List<User> result = null;
            try{
                result = QueryUtils.fetchJson(urls[0]);
            } catch (JSONException e) {
                Log.e(LOG_TAG,"Error in fetching json",e);
            }

            return result;
        }

        @Override
        protected void onPostExecute(List<User> users) {

            super.onPostExecute(users);
        }
    }
}

QueryUtils.java

public class QueryUtils {

    private static final String LOG_TAG = QueryUtils.class.getSimpleName();
    public QueryUtils() {
    }

    public static List<User> fetchJson(String requestUrl) throws JSONException{
        //create URL object
        URL url = createUrl(requestUrl);
        //perform http request to the URL and receive a json

        String jsonResponse = null;
        try {
            jsonResponse = makeHttpRequest(url);
        } catch (IOException e) {
            Log.e(LOG_TAG,"problem in making http request",e);
        }

        List<User> users = extractJson(jsonResponse);

        return users;
    }


    /**
     * Returns new URL object from the given string URL.
     */
    private static URL createUrl(String stringUrl){
        URL url = null;
        try{
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            Log.e(LOG_TAG,"Error in creating Url",e);
        }
        return url;
    }
    /**
     * Make an HTTP request to the given URL and return a String as the response.
     */
    private static String makeHttpRequest(URL url) throws IOException{
        String jsonResponse = "";
        //if url == null, return early
        if(url == null){
            return jsonResponse;
        }

        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            urlConnection = (HttpURLConnection)url.openConnection();
            urlConnection.setReadTimeout(10000);
            urlConnection.setConnectTimeout(15000);
            urlConnection.setRequestMethod("GET");

            if(urlConnection.getResponseCode() == 200){
                inputStream = urlConnection.getInputStream();
                jsonResponse = readFromStream(inputStream);
            }else {
                Log.e(LOG_TAG,"Error response code" + urlConnection.getResponseCode());
            }

        }catch (IOException e){
            Log.e(LOG_TAG,"Problem in retrieving Json Response",e);
        }finally {
            if (urlConnection != null){
                urlConnection.disconnect();
            }
            if (inputStream !=null){
                inputStream.close();
            }
        }
        return jsonResponse;
    }

    private static String readFromStream(InputStream inputStream) throws IOException {
        StringBuilder output = new StringBuilder();

        if(inputStream != null){
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            BufferedReader reader = new BufferedReader(inputStreamReader);

            String line = reader.readLine();

            while (line != null){
                output.append(line);
                line = reader.readLine();
            }
        }
        return output.toString();
    }

    private static List<User> extractJson(String json) throws JSONException{

        // If the JSON string is empty or null, then return early.
        if(TextUtils.isEmpty(json)){
            return null;
        }

        //create an empty arrylist
        List<User> users = new ArrayList<>();

        try{
            JSONArray jsonArray = new JSONArray();
            for (int i = 0; i<jsonArray.length(); i++){
                JSONObject jsonObject = jsonArray.getJSONObject(i);

                String login = jsonObject.getString("login");
                String type = jsonObject.getString("type");
                String avatar = jsonObject.getString("avatar_url");

                User user = new User(login,type,avatar);

                users.add(user);
            }
        }catch (JSONException e){
            Log.e(LOG_TAG,"Error in parsing the JSON",e);
        }

        return users;
    }
}

UserAdapter.java

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {

    ArrayList<User> users = new ArrayList<>();
    Context context;

    public UserAdapter(ArrayList<User> users, Context context) {
        this.users = users;
        this.context = context;
    }

    @Override
    public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items,parent,false);

        return new UserViewHolder(view);
    }

    @Override
    public void onBindViewHolder(UserViewHolder holder, int position) {
        holder.login.setText(users.get(position).getUser_login());
        holder.type.setText(users.get(position).getType());
        Picasso.with(context).load(String.valueOf(users.get(position))).into(holder.avatar);
    }

    @Override
    public int getItemCount() {
        return users.size();
    }

    public class UserViewHolder extends RecyclerView.ViewHolder {

        TextView login;
        TextView type;
        ImageView avatar;

        public UserViewHolder(View itemView) {
            super(itemView);
            login = (TextView)itemView.findViewById(R.id.login);
            type = (TextView)itemView.findViewById(R.id.type);
            avatar = (ImageView)itemView.findViewById(R.id.avatar);
        }
    }
}

User.java

public class User {

    private String user_login;
    private String type;
    private String url;

    public User(String user_login, String type, String url) {
        this.user_login = user_login;
        this.type = type;
        this.url = url;
    }

    public String getUser_login() {
        return user_login;
    }

    public String getType() {
        return type;
    }

    public String getUrl() {
        return url;
    }
}

2 个答案:

答案 0 :(得分:0)

更新代码:

在您的活动中:

public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
UserAdapter mAdapter;
RecyclerView.LayoutManager layoutManager;
private static final String JSON_URL = "https://api.github.com/users";
private static final String LOG_TAG = MainActivity.class.getSimpleName();

public ArrayList users = new ArrayList&lt;&gt;();

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


    recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    mAdapter = new UserAdapter(users,this);


    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(mAdapter);

    UserAsyncTask task = new UserAsyncTask();
    task.execute(JSON_URL);


}

在您的异步任务中:

public class UserAsyncTask extends AsyncTask<String, Void, List<User>>{
    @Override
    protected List<User> doInBackground(String... urls) {

        if(urls.length < 1 || urls[0] == null ){
            return null;
        }


        try{
            users = QueryUtils.fetchJson(urls[0]);
        } catch (JSONException e) {
            Log.e(LOG_TAG,"Error in fetching json",e);
        }


        return result;
    }

    @Override
    protected void onPostExecute(List<User> users) {

        super.onPostExecute(users);

if(users != null && !users.isEmpty()){

        mAdapter.notifyDataSetChanged();
    }
    }
}

或者使用您用于Listview的相同onPostExecute方法,并在recyclerview适配器中创建mAdapter.addAll(users);相同的方法。

答案 1 :(得分:0)

在适配器中创建以下方法:

清理数据:

public void clear() {
  int itemCount = getItemCount();
  users.clear();

  // notify your adapter that the data has been changed. You can also use notifyDataSetChanged() if you don't have an animation 
  if (itemCount > 0)
    notifyItemRangeRemoved(0, itemCount);
}

将项目添加到适配器:

public void addAll(List<User> addUsers) {
  for (User user : addUsers) {
    users.add(l_user);

    // notify your adapter that the data has been changed. You can also use notifyDataSetChanged() if you don't have an animation.
    // If you use notifyDataSetChanged() you can call it on the outside of this loop just once
    notifyItemInserted(users.size());
  }
}

现在,您可以在AsyncTask的onPostExecute()中调用这些方法:

@Override
protected void onPostExecute(List<User> users) {
  // clear the previous data
  mAdapter.clear();

  // add the new data
  if(users != null)
    mAdapter.addAll(users);
}