Android 片段管理器空对象引用
Android Fragment Manager Null Object Reference
@JavascriptInterface
public void switchView() {
//sync the BottomBar Icons since a different Thread is running
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run()
{
MapFragment mapFragment = new MapFragment();
FragmentManager fragmentManager = ((MainActivity) mContext).getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, mapFragment);
transaction.commit();
}
});
}
当我运行这段代码时一切正常,但是当我添加行
mapFragment.setUrl("www.examplestuff.com");
应用程序崩溃 尝试在空对象引用上调用虚拟方法 'void android.webkit.WebView.loadUrl(java.lang.String)'
我的片段 class 看起来像这样
public WebView mapView;
private String thisURL;
public void setUrl(String url) {
thisURL = url;
mapView.loadUrl(thisURL);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map,container, false);
mapView = (WebView)view.findViewById(R.id.mapView);
this.setUrl("file:///android_asset/www/MapView.html");
mapView.setWebViewClient(new WebViewClient());
WebSettings webSettings = mapView.getSettings();
webSettings.setJavaScriptEnabled(true);
//allow cross origin - like jsonP
webSettings.setAllowUniversalAccessFromFileURLs(true);
return view;
}
也在那里调用方法 this.setURL()
并且工作正常。
我做错了什么?
FragmentManager 是否无法访问片段的实例 WebView???
这是因为当您调用 setUrl
时它会调用此方法:
public void setUrl(String url) {
thisURL = url;
mapView.loadUrl(thisURL);
}
行 mapView.loadUrl(thisURL);
访问 mapView
。但是,您可能会在 Android 系统调用 onCreateView
之前调用 setUrl
,因此 mapView
为空,从而导致崩溃。
public void setUrl(String url) {
thisURL = url;
if(mapView != null) {
mapView.loadUrl(thisURL);
}
}
和
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map,container, false);
mapView = (WebView)view.findViewById(R.id.mapView);
if(thisUrl != null) {
mapView.loadUrl(thisURL);
}
... other code
那么 mapFragment.setUrl("www.examplestuff.com");
就可以了
更好的解决方案是更多地了解 Activity 和片段生命周期,而不是在 Fragment
处于无效状态时调用 setUrl
:-) 您可能正在调用 setUrl
当你真的应该在创建片段时将 Url 作为额外的意图传递。 https://developer.android.com/training/basics/fragments/communicating.html
@JavascriptInterface
public void switchView() {
//sync the BottomBar Icons since a different Thread is running
Handler refresh = new Handler(Looper.getMainLooper());
refresh.post(new Runnable() {
public void run()
{
MapFragment mapFragment = new MapFragment();
FragmentManager fragmentManager = ((MainActivity) mContext).getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.content, mapFragment);
transaction.commit();
}
});
}
当我运行这段代码时一切正常,但是当我添加行
mapFragment.setUrl("www.examplestuff.com");
应用程序崩溃 尝试在空对象引用上调用虚拟方法 'void android.webkit.WebView.loadUrl(java.lang.String)'
我的片段 class 看起来像这样
public WebView mapView;
private String thisURL;
public void setUrl(String url) {
thisURL = url;
mapView.loadUrl(thisURL);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map,container, false);
mapView = (WebView)view.findViewById(R.id.mapView);
this.setUrl("file:///android_asset/www/MapView.html");
mapView.setWebViewClient(new WebViewClient());
WebSettings webSettings = mapView.getSettings();
webSettings.setJavaScriptEnabled(true);
//allow cross origin - like jsonP
webSettings.setAllowUniversalAccessFromFileURLs(true);
return view;
}
也在那里调用方法 this.setURL()
并且工作正常。
我做错了什么? FragmentManager 是否无法访问片段的实例 WebView???
这是因为当您调用 setUrl
时它会调用此方法:
public void setUrl(String url) {
thisURL = url;
mapView.loadUrl(thisURL);
}
行 mapView.loadUrl(thisURL);
访问 mapView
。但是,您可能会在 Android 系统调用 onCreateView
之前调用 setUrl
,因此 mapView
为空,从而导致崩溃。
public void setUrl(String url) {
thisURL = url;
if(mapView != null) {
mapView.loadUrl(thisURL);
}
}
和
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map,container, false);
mapView = (WebView)view.findViewById(R.id.mapView);
if(thisUrl != null) {
mapView.loadUrl(thisURL);
}
... other code
那么 mapFragment.setUrl("www.examplestuff.com");
就可以了
更好的解决方案是更多地了解 Activity 和片段生命周期,而不是在 Fragment
处于无效状态时调用 setUrl
:-) 您可能正在调用 setUrl
当你真的应该在创建片段时将 Url 作为额外的意图传递。 https://developer.android.com/training/basics/fragments/communicating.html