【问题标题】:NullPointerException when attempting to pass string array from one class to another尝试将字符串数组从一个类传递到另一个类时出现 NullPointerException
【发布时间】:2015-07-15 23:25:37
【问题描述】:

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

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(); 行。

我做错了什么?

编辑:

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

HarvesterAsync 是一个AsyncTask。你可以看到它here

【问题讨论】:

  • 嗯,metaDataFetcher 似乎是 null
  • 好像metaDataFetchernull
  • 我明白,但为什么呢?
  • @Segadude 我认为这是范围问题。你能摆脱 try catch 块并查看你的代码行为吗?
  • 嗨,请发布更多关于“metaDataFetcher”如何被初始化以及“HarvesterAsync”是什么样子的代码,尤其是“HarvesterAsync.get()”方法的作用。我觉得对于asynTask,执行后直接获取即可

标签: java android nullpointerexception


【解决方案1】:

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

String[] receivedMetaData = metaDataFetcher.getMetaData(); 

将立即从 MetaDataFetcher 的字段中返回收到的MetaData,而不是 HarvesterAsync 的结果。

【讨论】:

    【解决方案2】:

    在这些情况下,您需要使用回调。您不能调用AsyncTaskexecute() 并立即开始使用返回的值,因为AsyncTask 在单独的线程上运行,您将遇到@inmyth 以及cmets 中的其他人提到的并发问题。

    因此,为了使其正常工作,您需要做的是使用回调。一开始,这可能看起来像是一个牵强的解决方案,但相信我,当您尝试实施大型项目时,它会带来回报。

    首先,在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,因为一旦它被AsyncTask加载,AsyncTask就会回调onFetchComplete

    【讨论】:

      猜你喜欢
      • 2015-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 2013-04-12
      相关资源
      最近更新 更多