【问题标题】:null return when i should be getting a <String> **edited**当我应该得到一个 <String> **edited** 时返回 null
【发布时间】:2017-05-13 08:48:05
【问题描述】:

已编辑忘记包含实际问题。

所以我知道我的文件正在返回 null,因为我的“GetData()”调用正在流经我的其余脚本导致错误。但是,我不知道如何防止这种情况。有人能指出我正确的方向吗?

问题 我得到的错误是 Attempt to invoke virtual method 'java.lang.Object[] java.util.ArrayList.toArray()' on a null object reference

根据我的理解,当我使用这条线时 titles = readRss.titles; 它通过这个订单拉一个空响应。ReadRss > ProcessXml() > Getdata() 并且由于获取数据是“尝试”“捕获”部分,因此它同时返回 xmldoc 和 null。

当我在我的 ProcessXml() 中登录时,我可以获得完整的标题列表,并且我可以单独记录提要项目,但是如果我尝试在此之外登录,它会返回 null。

我误会了什么。

ReadRss 脚本:

public class ReadRss extends AsyncTask<Void, Void, Void> {
ArrayList<String>titles;


BlankFragment context;
String address="https://www.sciencemag.org/rss/news_current.xml";
//ProgressDialog progressDialog;
ArrayList<FeedItem> feedItems;
RecyclerView recyclerView;
URL url;
public ReadRss(BlankFragment context, RecyclerView recyclerView){
    this.recyclerView=recyclerView;
    this.context=context;
   // progressDialog = new ProgressDialog(context);
   // progressDialog.setMessage("Loading...");
}

@Override
protected void onPreExecute() {
    //progressDialog.show();
    super.onPreExecute();
}



@Override
public void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    //progressDialog.dismiss();


}

@Override
public Void doInBackground(Void... voids) {
    ProcessXml(Getdata());
    return null;
}


public ArrayList<String> ProcessXml(Document data) {

    if (data!=null) {
        titles=new ArrayList<>();
        feedItems=new ArrayList<>();
        Element root=data.getDocumentElement();
        Node channel=root.getChildNodes().item(1);
        NodeList items=channel.getChildNodes();
        for (int i=0;i<items.getLength();i++){
            Node currentchild=items.item(i);
            if (currentchild.getNodeName().equalsIgnoreCase("item")){
                FeedItem item=new FeedItem();
                NodeList itemchilds=currentchild.getChildNodes();
                for (int j=0;j<itemchilds.getLength();j++){
                    Node current=itemchilds.item(j);
                    if (current.getNodeName().equalsIgnoreCase("title")){
                        item.setTitle(current.getTextContent());
                        titles.add(current.getTextContent());
                    }else if (current.getNodeName().equalsIgnoreCase("description")){
                        item.setDescription(current.getTextContent());
                    }else if (current.getNodeName().equalsIgnoreCase("pubDate")){
                        item.setPubDate(current.getTextContent());
                    }else if (current.getNodeName().equalsIgnoreCase("link")){
                        item.setLink(current.getTextContent());
                    }else if (current.getNodeName().equalsIgnoreCase("media:thumbnail")){
                        String url=current.getAttributes().item(0).getTextContent();
                        item.setThumbnailUrl(url);
                    }

                }
                feedItems.add(item);
                Log.d("hello", item.getTitle());


            }

        }
    }

    return titles;


}

public Document Getdata(){
    try{

        url = new URL(address);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        InputStream inputStream = connection.getInputStream();
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document xmlDoc = builder.parse(inputStream);
        return xmlDoc;
    } catch (Exception e){
        e.printStackTrace();

    }


    return null;
}




}

BlankFragment 脚本调用标题。

public class BlankFragment extends Fragment {
ArrayList<FeedItem>feedItems;
ArrayList<String>titles;

String address="https://www.sciencemag.org/rss/news_current.xml";
URL url;



public BlankFragment() {
    // Required empty public constructor
}

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

}

@TargetApi(Build.VERSION_CODES.N)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_blank, container, false);

    RecyclerView rv = (RecyclerView) rootView.findViewById(R.id.rv_recycler_view);
    rv.setHasFixedSize(true);

    ReadRss readRss = new ReadRss(this, rv);
    readRss.getClass();




    titles = readRss.titles;



    String[] display_titles = (String[]) titles.toArray();











    //Document data = readRss.Getdata();
    //ArrayList<FeedItem> feedItems = readRss.ProcessXml(data);



    MyAdapter adapter = new MyAdapter(display_titles);
    rv.setAdapter(adapter);

    LinearLayoutManager llm = new LinearLayoutManager(getActivity());
    rv.setLayoutManager(llm);

    return rootView;
}




}

【问题讨论】:

  • 下面我的回答对您有帮助吗?您可以通过记录何时实例化“标题”以及何时使用它来测试它 - 这会让您知道哪个先发生
  • 对不起,假期让我离开了。我现在才回到这个项目。谢谢,对我帮助很大。

标签: java string android-studio null return


【解决方案1】:

这是一种竞争条件,尽管听起来一条路径总能赢得竞争。 您正在使用 2 个线程;

  1. 线程 1(可能是 UI 线程)- 创建 ReadRss - 读取“标题”
  2. 后台线程 - 执行 GetData() - 执行 ProcessXml() - 设置“标题”

如果主线程在后台线程开始实例化之前到达读取“标题”的点 - 那么“标题”将为空。

也许在创建 AsyncTask 之后,您可以继续创建视图 - 在标题所在的位置显示“正在加载”。然后,当 AsyncTask 完成时,它可以使用标题更新视图 - onPostExecute()。

【讨论】:

  • 这帮助我意识到我做错了什么,但是我不知道如何解决它。至少这样我可以更好地理解需要做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
  • 2020-02-27
  • 1970-01-01
  • 2015-07-09
  • 2016-04-25
  • 1970-01-01
  • 2017-01-03
相关资源
最近更新 更多