为啥我得到 null 而不是 Map 对象?如何解决这个问题?
Posted
技术标签:
【中文标题】为啥我得到 null 而不是 Map 对象?如何解决这个问题?【英文标题】:Why I got null instead of Map object? How to fix this?为什么我得到 null 而不是 Map 对象?如何解决这个问题? 【发布时间】:2013-02-21 05:10:45 【问题描述】:我正在编写一个 android 应用程序,但遇到了一个问题:我得到了一个 null 而不是 ImmutableMap 对象。看来我的地图正在被垃圾收集。但我创建了对它的引用。所以这是我所有的源代码,其中详细描述了 cmets 中的问题:
//I have a BaseActivity class in which i defined nested class
//which incapsulates some REST operations
public class BaseActivity extends Activity
//Here is this ImmutableMap to which I want save the result
private ImmutableMap<String, Object> serverData_;
//Here is this nested class which is AsyncTask
class RestfulNetworkTasks extends AsyncTask
<Pair<String,LinkedHashMap<String, Object>>, Void, LinkedHashMap<String, Object>>
NetworkOperation LowLevelRestOperations_ = new NetworkOperation();
@Override
protected LinkedHashMap<String, Object> doInBackground(Pair<String,LinkedHashMap<String, Object>>... params)
return LowLevelRestOperations_.executeServerCommand
(params[0].getValue0(), params[0].getValue1());
protected void onPostExecute(LinkedHashMap<String, Object> result)
//Here i created a reference to the result(in order
//to save it in my data structure)
serverData_ = copyOf(result);
UpdateCurrentActivityAfterNetworkOperation();
//Here I made a test output to check if i got the result
//All is good - I got a correct result saved to serverData_
android.util.Log.d("TEST RESPONSE", "ON POST" + serverData_);
//End of nested class declaration
//Here is my method in which i want to call AsyncTask and got a problem
public void Login(LinkedHashMap<String,Object> parameters)
//Here I create an instance of that nested AsyncTask class
RestfulNetworkTasks serverOperation_ = new RestfulNetworkTasks();
Pair<String, LinkedHashMap<String, Object>> params_ =
new Pair<String,LinkedHashMap<String,Object>>(LOGIN_COMMAND, parameters);
//Here I call AsyncTask operation - i got a correct ON POST output
//with correct data
serverOperation_.execute(params_);
//But from this point my serverData_ is null!
//And I got null in AFTER POST output!Why?serverData_ is a member of BaseActivity so
//it have to keep the result.
android.util.Log.d("TEST RESPONSE", "AFTER POST" + serverData_);
那么如何解决这个问题?为什么调用execute后我的serverData_为null?
我真的需要帮助 - 我真的是 Java 和 Android 的新手,这个问题让我发疯了。提前致谢。
【问题讨论】:
你的代码风格会让经验丰富的 Java 程序员哭泣。 1)压痕看起来像狗早餐。 2) 变量和方法名称应始终以小写字母开头。 3) 变量名中不应使用下划线字符。 4)如果你的缩进是正确的,你就不会像//End of nested class declaration
@StephenC 感谢 cmets。我还在学习。我说:“我对 Java 真的很陌生……”。所以对于一个经验丰富的 Java 程序员来说,我可能看起来像个孩子。
ImmutableMap 是 com.google.common.collect.ImmutableMap?
@pomkine 是的。来自 Google Guava
@HarryCater 所以你应该尝试像这样初始化 Map: ImmutableMap.Builder调用执行后我的 serverData_ 为空?
因为 AsyncTasks 是在单个后台线程上串行执行的,而不会在 UI 线程(如线程)上等待,直到线程执行未完成。
如果您想在主 ui 线程上等待,直到 AsyncTasks 计算未完成并返回结果,请使用 AsyncTask.get() 。
例子:
serverOperation_.execute(params_).get(); //<<<<
// now u get latest value in serverData_
android.util.Log.d("TEST RESPONSE", "AFTER POST" + serverData_);
【讨论】:
好的。这是用我当前的实现设计保存结果的唯一方法吗?并且“如果您想在主 ui 线程上等待直到 AsyncTasks 计算未完成”会不会导致性能开销? @HarryCater :是的,如果您使用 AsyncTask.get() 从 AsyncTask 获取结果,这将冻结当前 UI,直到 AsyncTask 计算未完成(或控制直到返回主 UI 线程才返回)。而不是使用 AsyncTask.get() 使用 onPostExecute 方法【参考方案2】:看来我的地图正在被垃圾收集。
不,这不是问题。您可能使用的对象不会被垃圾收集。从来没有。
真正的问题是变量在使用之前没有被赋值。
【讨论】:
【参考方案3】:似乎对象 serverData_ 尚未初始化,在您调用的代码中 serverData_ = copyOf(result);线程中的语句,可能会在将来执行,在此之前您使用 serverData_ 在 onPostExecute 完成之前将为空。请等到您的 AsyncTask 完成。
【讨论】:
【参考方案4】:问题在于 ImmutableMap。如果这是 google 版本,一旦创建就无法更改。一种解决方案是使用常规的 java 库函数来分配和构建 Map,然后使用 Collections 接口返回和不可修改的视图;类似:
HashMap<String, Object> modifiableMap = new HashMap<String, Object>();
modifiableMap.put("1", new Object());
modifiableMap.put("2", new Object());
Map<String, Object> unmodifiableMap = Collections.unmodifiableMap(modifiableMap);
或者,您可以坚持使用 google 实现,但您需要使用他们的构建器方法;类似:
ImmutableMap<String, Object> map = ImmutableMap.builder()
.put(key, value);
.build();
【讨论】:
以上是关于为啥我得到 null 而不是 Map 对象?如何解决这个问题?的主要内容,如果未能解决你的问题,请参考以下文章
为啥如果我得到计算对象中的对象属性未定义而不是对象本身?哪种方法更适合这种情况?
在使用 map 循环遍历数组时返回 null 而不是 JSX