首页 > 解决方案 > 为什么我的字符串没有在 AsyncTask 中填充?

问题描述

我的字符串(这是字符串:headings[]、descs[]、url[]、urlToImg[])在我使用它们后被初始化,这导致了 nullPointerException!如何实现字符串初始化,以便我的字符串可以动态初始化?

在这里,我在 parseResult() 方法的帮助下初始化字符串运行时,该方法由扩展 AsyncTask 类的类调用。passrseResult() 方法正在初始化字符串!但与此同时,在创建“NewsAdapter”对象时,主线程在 onCreate() 方法中使用了字符串,因此字符串为空,导致 nullPointerException!

package com.example.pritam.medoc;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Objects;

public class FragmentNews extends Fragment {


    String newsAPIUrl;

    ListView newsList;
    String headings[];
    String descs[];
    String url[];
    String urlToImg[];
    //strore url for images in string[]

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


        newsAPIUrl ="Some APIKey that i have";
        new AsyncHTTPTask().execute(newsAPIUrl);


        View v=inflater.inflate(R.layout.fragment_news,container,false);
        newsList=v.findViewById(R.id.listview_news);


        NewsAdapter newsAdapter=new NewsAdapter(Objects.requireNonNull(getActivity()).getApplicationContext(),headings,descs,url,urlToImg);
        newsList.setAdapter(newsAdapter);

        /*newsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                //this how to acces link from adapter table String a[]=newsAdapter.adp_descs;
                //redirect to the news!

            }
        });*/


        return inflater.inflate(R.layout.fragment_news,container,false);
    }

    class NewsAdapter extends ArrayAdapter<String>
    {
        Context context;
        String adp_headings[];
        String adp_descs[];
        String adp_url[];
        String adp_urlToImg[];
        //try to store url for images
        NewsAdapter(Context c, String _head[], String _desc[],String _url[], String _urlToImg[])
        {
            super(c,R.layout.adapter_listview,R.id.news_heading,_head);
            this.context=c;
            this.adp_headings=_head;
            this.adp_descs=_desc;
            this.adp_url=_url;
            this.adp_urlToImg=_urlToImg;
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            LayoutInflater layoutInflater=(LayoutInflater)getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View customListLayout=layoutInflater.inflate(R.layout.adapter_listview,parent,false);

            ImageView news_img=customListLayout.findViewById(R.id.news_image);
            TextView news_head=customListLayout.findViewById(R.id.news_heading);
            TextView news_desc=customListLayout.findViewById(R.id.news_desc);

            //here try to populate image from url news_img.setImageResource();
            news_head.setText(adp_headings[position]);
            news_desc.setText(adp_descs[position]);

            return customListLayout;
        }
    }

    public class AsyncHTTPTask extends AsyncTask<String, Void, String>
    {

        @Override
        protected String doInBackground(String... urls) {
            String result="";
            URL this_url;
            HttpURLConnection urlConnection;
            try{
                this_url=new URL(urls[0]);
                urlConnection=(HttpURLConnection)this_url.openConnection();
                String response=streamToString(urlConnection.getInputStream());
                parseResult(response);
                return response;
            }
            catch (Exception e)
            {
             Log.i("",e.toString());
            }
            return null;
        }
    }

    String streamToString(InputStream stream)throws IOException
    {
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(stream));
        String data;
        String result="";

        while ((data=bufferedReader.readLine()) != null)
        {
            result+=data;
        }
        if(null != stream)
        {
            stream.close();
        }
        return result;
    }

    private void parseResult(String result) throws JSONException {
        JSONObject response=new JSONObject(result);
        JSONArray articles=response.optJSONArray("articles");

        headings=new String[articles.length()];
        descs=new String[articles.length()];
        url=new String[articles.length()];
        urlToImg=new String[articles.length()];

        for(int i=0; i<articles.length(); i++)
        {
            JSONObject article=articles.optJSONObject(i);
            headings[i]=article.optString("title");
            //Log.i("Title",headings[i]);

            descs[i]=article.optString("description");
            //Log.i("Description",descs[i]);

            url[i]=article.optString("url");
            //Log.i("url",url[i]);

            urlToImg[i]=article.optString("urlToImage");
            //Log.i("urlToImage",urlToImg[i]);
        }
    }
}

在创建 NewsAdapter 的对象时,我得到了那个错误!

标签: javaandroid

解决方案


您的字符串没有被填充,因为AsyncTask用于获取数据的代码和用于填充列表的代码并行运行。当您的异步任务完成执行时,该列表已被填充。您需要了解异步任务中编码的任务发生在单独的线程中。

您要做的是在异步任务从 API 获取数据后填充列表。您必须检查如何从异步任务中更新您的列表(您可能想搜索 method runOnUiThread。我可能对这种方法有误,因为我在 Android 上工作已经很长时间了。但我确信我的方法是正确的) .

您还可以查看以下链接。

如何从异步任务更新 ui

Android 基础:在 UI 线程中运行代码


推荐阅读