尝试将字符串数组从一个类传递到另一个类时出现NullPointerException

时间:2015-05-06 02:17:49

标签: java android nullpointerexception

在我的Android应用中,我需要在我的应用中的两个不同位置使用一些字符串。所以我写了一个类,我可以从中获取这些字符串。当我尝试从返回字符串数组的类调用return方法时,应用程序与java.lang.NullPointerException崩溃。这是带有return方法的类:

public class MetaDataFetcher {

    String[] metaData;

    public String[] getMetaData() {
        //Gets the metadata strings from HarvasterAsync
        try {
            metaData = new HarvesterAsync().execute("urlhere").get();



        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return metaData;
    }
}

我试图像这样检索字符串数组:

public void updateMetaData(){
//Gets the metadata strings from MetaDataFetcher

String[] receivedMetaData = metaDataFetcher.getMetaData(); 

//More code below...

NullPointerException发生在String[] receivedMetaData = metaDataFetcher.getMetaData();行。

我做错了什么?

编辑:

我使用MetaDataFetcher类中onCreate方法上方的MetaDataFetcher metaDataFetcher;行初始化MainActivity类。

HarvesterAsync是AsyncTask。你可以看到它here

2 个答案:

答案 0 :(得分:0)

问题是并发性。 AsyncTask是非阻塞的。所以基本上这个

String[] receivedMetaData = metaDataFetcher.getMetaData(); 

将立即从MetaDataFetcher的字段返回receivedMetaData,而不是HarvesterAsync的结果。

答案 1 :(得分:0)

在这种情况下,您需要使用回调。你无法调用execute()的{​​{1}}并立即开始使用返回的值,因为AsyncTask在一个单独的线程上运行,你也会遇到@inmyth所提到的并发问题和评论中的其他人一样。

所以你需要做的才能使其工作是使用回调。在开始时,这可能看起来像一个牵强附会的解决方案,但相信我,当你尝试实施大型项目时它会得到回报。

首先,在AsyncTask类中声明一个侦听器接口,您可以在任何想要从HarvesterAsync

获取值的地方实现这些侦听器

以下是一个示例:

AsncTask

现在要获得结果,您可以像这样实现侦听器接口:

public class HarvesterAsync extends AsyncTask<...> {
    // declare your variables
    private List<HarvesterAsyncListener> harvestListeners;

    public HarvesterAsync() {
        // initialise all variables
        harvestListeners = new ArrayList<HarvestAsyncListener>();
    }

    @Override
    protected void doInBackground() {
        // ...
        // fetch your data from somewhere and load it into say "metaData"
        String[] metaData = fetchYourData();

        // notify all listeners that the data has been successfully fetched
        for(listener: harvestListeners) {
            // pass in your result to the method of the interface
            listener.onFetchComplete(metaData);
        }
    }

    // use this method to add new listeners to harvestListeners
    public void addListener(HarvestListener listener) {
        harvestListeners.add(listener);
    }

    public interface HarvestAsyncListener {
        public void onFetchComplete(String[] metaData);
    }
}

您当然可以更改界面中的方法签名以满足您的要求。

此处您无需返回public class MetaDataFetcher implements HarvesterAsync.HarvesterAsyncListener { String[] metaData; public void getMetaData() { // initailize the AsyncTask HarvestAsync harvestAsnc = new HarvestAsync(); // add the listener harvestAsync.addListener(this); ... } @Override public void onFetchComplete(String[] metaData) { // do whatever you want with metaData. this.metaData = metaData; .... } } ,因为metaData一旦加载AsyncTaskAsyncTask就会回复onFetchComplete