[英]NullPointerException when attempting to pass string array from one class to another
In my Android app, there are some strings that I need to use in two different places in my app. 在我的Android应用中,我需要在我的应用中的两个不同位置使用一些字符串。 So I wrote a class from which I can get these strings.
所以我写了一个类,我可以从中获取这些字符串。 When I try to call the return method from the class that returns the string array, the app crashes with
java.lang.NullPointerException
. 当我尝试从返回字符串数组的类调用return方法时,应用程序崩溃了
java.lang.NullPointerException
。 Here is the class with the return method: 这是带有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;
}
}
I am attempting to retrieve the string array like this: 我试图像这样检索字符串数组:
public void updateMetaData(){
//Gets the metadata strings from MetaDataFetcher
String[] receivedMetaData = metaDataFetcher.getMetaData();
//More code below...
The NullPointerException occurs at the line String[] receivedMetaData = metaDataFetcher.getMetaData();
NullPointerException发生在
String[] receivedMetaData = metaDataFetcher.getMetaData();
. 。
What am I doing wrong? 我究竟做错了什么?
Edit: 编辑:
I initialize the MetaDataFetcher
class with the line MetaDataFetcher metaDataFetcher;
我使用
MetaDataFetcher metaDataFetcher;
行初始化MetaDataFetcher
类MetaDataFetcher metaDataFetcher;
above the onCreate method in my MainActivity
class. 在我的
MainActivity
类中的onCreate方法之上。
HarvesterAsync is an AsyncTask
. HarvesterAsync是一个
AsyncTask
。 You can see it here . 你可以在这里看到它。
The problem is concurrency. 问题是并发性。 AsyncTask is non-blocking.
AsyncTask是非阻塞的。 So basically this
所以基本上这个
String[] receivedMetaData = metaDataFetcher.getMetaData();
will immediately return the receivedMetaData from MetaDataFetcher's field not the result of HarvesterAsync. 将立即从MetaDataFetcher的字段返回receivedMetaData,而不是HarvesterAsync的结果。
In these sort of situations you need to make use of callbacks .
在这种情况下,您需要使用回调 。 You cannot call
execute()
of an AsyncTask
and right away start using the value returned because the AsyncTask
runs on a separate thread and you will have the problem of concurrency as mentioned by @inmyth as well as others in the comments. 您不能调用
AsyncTask
execute()
并立即开始使用返回的值,因为AsyncTask
在单独的线程上运行,并且您将遇到@inmyth以及注释中的其他人提到的并发问题。
So what you need to do in-order to make it work is use callbacks. 因此,为了使其工作,您需要做的是使用回调。 At the beginning this might look like a far-fetched solution but trust me it pays off when you are trying to implement large projects.
在开始时,这可能看起来像一个牵强附会的解决方案,但相信我,当你试图实施大型项目时它会得到回报。
First off, declare a listener interface inside your HarvesterAsync
class and you can implement these listeners wherever you want to get the value from the AsncTask
首先,在
HarvesterAsync
类中声明一个监听器接口,你可以在任何想要从AsncTask
获取值的地方实现这些监听AsncTask
Here is a sample: 这是一个示例:
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);
}
}
Now to obtain the result you can implement the listener interface like this: 现在要获得结果,您可以像这样实现侦听器接口:
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;
....
}
}
You could of course change the method signature in the interface to suit your requirements. 您当然可以更改界面中的方法签名以满足您的要求。
Here you don't need to return the metaData
because once it is loaded by the AsyncTask
, the AsyncTask
does a callback to the onFetchComplete
. 在这里,您不需要返回
metaData
因为一旦AsyncTask
加载了它, AsyncTask
就会对onFetchComplete
进行回调。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.