在我的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。
答案 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
一旦加载AsyncTask
,AsyncTask
就会回复onFetchComplete
。