ArrayList.add 不适用于 AsyncTask

Posted

技术标签:

【中文标题】ArrayList.add 不适用于 AsyncTask【英文标题】:ArrayList.add not working with AsyncTask 【发布时间】:2018-12-09 07:14:53 【问题描述】:

我正在使用片段视图在我的 android 应用程序中显示 ListView。当我手动输入ArrayList 时,它工作得很好。但现在我想将 JSON 数组添加到 AsyncTask 类中的 ArryList 并将 ArrayList 添加到适配器。

所以我得到了 JSON 数组并将其放入 ArrayList。这个过程在AsyncTask 类中进行。

我在 Fragment 的 onCreateView() 方法中执行 AsyncTask 类。然后我将ArrayList 设置为适配器。但是问题就在那里..

执行AsyncTask 类后,完美获取我的JSON 数组并添加到ArrayList。但是当我尝试将我的ArrayList 添加到适配器时。然后我的ArryaList 为空。

这是我的带有AsyncTask 部分的片段类

public class FragmentCategory extends Fragment 

private ListView lvCategory;
private CategoryAdapter categotyAdapter;
private List<Category> mCategoryLst;

View view;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 

    view = inflater.inflate(R.layout.fragment_category , container, false);
    lvCategory = (ListView) view.findViewById(R.id.listview_category);
    mCategoryLst = new ArrayList<>();
    /*mCategoryLst.add(new Category(1, "hghjj" ,null));
    mCategoryLst.add(new Category(2,"Abcd", null));
    mCategoryLst.add(new Category(3,"Aeec", null));*/
    new FetchDataTask().execute();
    if(mCategoryLst!=null && mCategoryLst.size()>0) 
        categotyAdapter = new CategoryAdapter(getContext(), mCategoryLst);
    

    lvCategory.setAdapter(categotyAdapter);
    return view;


@Override
public void onCreate(@Nullable Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    //new FetchDataTask().execute();


public class FetchDataTask extends AsyncTask<String,String,Void>

    private ProgressDialog progressDialog = new ProgressDialog(getActivity());
    private String mUrlCategory;
    @Override
    protected void onPreExecute() 
        progressDialog.setMessage("Downloading your data...");
        progressDialog.show();
        progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() 
            public void onCancel(DialogInterface arg0) 
                FetchDataTask.this.cancel(true);
            
        );
    

    @Override
    protected Void doInBackground(String... strings) 
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        Uri bUri = Uri.parse(getString(R.string.url_category));
        URL url;
        try 
            url = new URL(bUri.toString());
            urlConnection = (HttpURLConnection)url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();

            if(inputStream==null)
            
                return null;
            

            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null)
            
                buffer.append(line + "\n");
            

            if(buffer.length() == 0)
            
                return null;
            
            mUrlCategory = buffer.toString();                

        
        catch (MalformedURLException e) 
        e.printStackTrace();
         catch (IOException e) 
        e.printStackTrace();
         /*catch (JSONException e) 
        e.printStackTrace();
         */finally 
            if (urlConnection != null) 
                urlConnection.disconnect();
            
            if (reader != null) 
                try 
                    reader.close();
                 catch (final IOException e) 
                    Log.e("MainActivity", "Error closing stream", e);
                
            
        
        return null;
    

    @Override
    protected void onPostExecute(Void aVoid) 
        try 
            if (progressDialog.isShowing())
                progressDialog.dismiss();
            JSONArray jArray = new JSONArray(mUrlCategory);
            for (int i = 0; i < jArray.length(); i++) 

                JSONObject jObject = jArray.getJSONObject(i);

                int id = Integer.parseInt(jObject.getString("id"));
                String name = jObject.getString("categoryName");
                String imageUrl = jObject.getString("iconPath");

                mCategoryLst.add(new Category(id, name ,null));
            
     catch (JSONException e) 
    Log.e("JSONException", "Error: " + e.toString());
 // catch (Exception e)
    



这是我的类别类 这个用于创建ArrayList

public class Category 

private  int categoryId;
private String categoryName;
private String imgUrl;

public Category()




public Category(int id,String name, String img)

    this.categoryId=id;
    this.categoryName=name;
    this.imgUrl=img;


//Gettert

public int getCategoryId() 
    return categoryId;


public String getCategoryName() 
    return categoryName;



public String getImgUrl() 
    return imgUrl;


//Settert


public void setCategoryId(int categoryId) 
    this.categoryId = categoryId;


public void setCategoryName(String categoryName) 
    this.categoryName = categoryName;


public void setImgUrl(String imgUrl) 
    this.imgUrl = imgUrl;


这是我的适配器类

public class CategoryAdapter extends BaseAdapter 

private Context mContext;
private List<Category> mCategoryList;

//Constructor


public CategoryAdapter(Context mContext, List<Category> mCategoryList) 
    this.mContext = mContext;
    this.mCategoryList = mCategoryList;


@Override
public int getCount() 
    return mCategoryList.size();


@Override
public Object getItem(int position) 
    return mCategoryList.get(position);


@Override
public long getItemId(int position) 
    return position;


@Override
public View getView(int position, View convertView, ViewGroup parent) 
    View v = View.inflate(mContext, R.layout.item_category, null);
    TextView tvCategoryName = (TextView) v.findViewById(R.id.category_name);
    ImageView ivCategoryImg = (ImageView) v.findViewById(R.id.img_category);
    //Set Value
    tvCategoryName.setText(mCategoryList.get(position).getCategoryName());
    //ivCategoryImg.setImageResource();
    //Set ID
    v.setTag(mCategoryList.get(position).getCategoryId());

    return v;


【问题讨论】:

在你的 onPostExecute 方法中添加这一行 categotyAdapter = new CategoryAdapter(getContext(), mCategoryLst); lvCategory.setAdapter(categotyAdapter); 它将起作用 mCategoryLst 中添加数据后更好地使用categotyAdapter.notifyDataSetChanged(); onPostExecute onPostExecute asynctask 方法 @Nilesh 谢谢你..它的工作... 【参考方案1】:
categotyAdapter = new CategoryAdapter(getActivity(), mCategoryLst); 
lvCategory.setAdapter(categotyAdapter);

【讨论】:

虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案2】:

根据您的代码,我所看到的,对 AysncTask 类的 Fragment OnCreateView() 和 OnPostExecution 进行如下代码的更改。

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 

    view = inflater.inflate(R.layout.fragment_category , container, false);
    lvCategory = (ListView) view.findViewById(R.id.listview_category);
    mCategoryLst = new ArrayList<>();
    /*mCategoryLst.add(new Category(1, "hghjj" ,null));
    mCategoryLst.add(new Category(2,"Abcd", null));
    mCategoryLst.add(new Category(3,"Aeec", null));*/
    new FetchDataTask().execute();

 categotyAdapter = new CategoryAdapter(getContext(), mCategoryLst);
    lvCategory.setAdapter(categotyAdapter);
    return view;

在 OpPostExecution 中

protected void onPostExecute(Void aVoid) 
        try 
            if (progressDialog.isShowing())
                progressDialog.dismiss();
            JSONArray jArray = new JSONArray(mUrlCategory);
            for (int i = 0; i < jArray.length(); i++) 

                JSONObject jObject = jArray.getJSONObject(i);

                int id = Integer.parseInt(jObject.getString("id"));
                String name = jObject.getString("categoryName");
                String imageUrl = jObject.getString("iconPath");

                mCategoryLst.add(new Category(id, name ,null));
            
    categotyAdapter.notifyDataSetChanged();
     catch (JSONException e) 
    Log.e("JSONException", "Error: " + e.toString());
 // catch (Exception e)
    

【讨论】:

这对我不起作用。但谢谢。你的回答帮助我解决了这个问题【参考方案3】:

问题已解决 我像这样更改我的onPostExecute() 方法...

@Override
protected void onPostExecute(Void aVoid) 
    try 
        if (progressDialog.isShowing())
            progressDialog.dismiss();
        JSONObject jsonObject = new JSONObject(mUrlCategory);

        Log.v("Response", jsonObject.toString());

        JSONArray categoryArray = jsonObject.getJSONArray("itemcategory");
        for (int i = 0; i < categoryArray.length(); i++) 

            JSONObject jCategory = (JSONObject) categoryArray.get(i);

            int id = Integer.parseInt(jCategory.getString("id"));
            String name = jCategory.getString("categoryName");
            String imageUrl = jCategory.getString("iconPath");

            mCategoryLst.add(new Category(id, name, null));
        

        if (mCategoryLst != null && mCategoryLst.size() > 0) 
            categotyAdapter = new CategoryAdapter(getContext(), mCategoryLst);
        

        lvCategory.setAdapter(categotyAdapter);
        categotyAdapter.notifyDataSetChanged();
     catch (JSONException e) 
        Log.e("JSONException", "Error: " + e.toString());
     // catch (Exception e)

当我放这部分时

if (mCategoryLst != null && mCategoryLst.size() > 0) 
    categotyAdapter = new CategoryAdapter(getContext(), mCategoryLst);


lvCategory.setAdapter(categotyAdapter);

OnCreateView() 应用程序不工作。所以我把它放在onPostExecute()。然后它完美地工作。谢谢大家

【讨论】:

【参考方案4】:

当你有数据时,你需要在你的适配器上调用notifyDataSetChanged()

 for (int i = 0; i < jArray.length(); i++) 

     JSONObject jObject = jArray.getJSONObject(i);

     int id = Integer.parseInt(jObject.getString("id"));
     String name = jObject.getString("categoryName");
     String imageUrl = jObject.getString("iconPath");

     mCategoryLst.add(new Category(id, name, null));
 
 categotyAdapter.notifyDataSetChanged();

【讨论】:

以上是关于ArrayList.add 不适用于 AsyncTask的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList.add 抛出 ArrayIndexOutOfBoundsException [重复]

显示未能找到类型或命名空间名称“Arraylist”(是不是缺少using指令或程序集引用)求大神解

list遍历时删除元素

ArrayList add get remove 源码解析

ArrayList add() 有时不会将从 Firebase 获取的元素添加到 ArrayList

纯并行添加的Java ArrayList.add() 方法线程安全吗? [复制]