У меня есть приложение ViewPager с 7 вкладками. Все вкладки являются веб-представлениями. Приложение прекрасно работает, пока я не переключаюсь из приложения.
Если я вернусь к приложению до того, как ActivityManager выгонит меня, оно все равно будет отлично работать. Проблема возникает, когда меня выгнали из памяти. Он возвращается, восстанавливает правильную вкладку и затем вылетает. Я попытался удалить вызов initWebView (см. Ниже). Этот метод восстанавливает настройки, такие как включение сценария Java. Если я не выполняю эту инициализацию при восстановлении, она не падает, но оставляет страницы пустыми (я предполагаю, потому что я не вызвал mWebView.getSettings (). SetJavaScriptEnabled (true).
Вот код для двух файлов:
package com.mobilityinitiative.synergyworldwide;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
public class SynergyWorldwideActivity extends SherlockFragmentActivity
{
final static private String tag = SynergyWorldwideActivity.class.getSimpleName();
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
final static private int mMaxTabs = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(tag,"onCreate");
// Set up the view pager
setContentView(R.layout.fragment_tabs_pager);
mViewPager = (ViewPager)findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(mMaxTabs);
// Set up action bar
final ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(true);
// Test for internet connectivity
if(!isOnline())
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.internet_not_on)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
SynergyWorldwideActivity.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
// Creat tabs with bundled URLs
Bundle tab1Args=new Bundle(), tab2Args=new Bundle(), tab3Args=new Bundle(),
tab4Args=new Bundle(), tab5Args=new Bundle(), tab6Args=new Bundle(), tab7Args=new Bundle();
tab1Args.putString("tabURL", getString(R.string.webtab1_URL));
tab2Args.putString("tabURL", getString(R.string.webtab2_URL));
tab3Args.putString("tabURL", getString(R.string.webtab3_URL));
tab4Args.putString("tabURL", getString(R.string.webtab4_URL));
tab5Args.putString("tabURL", getString(R.string.webtab5_URL));
tab6Args.putString("tabURL", getString(R.string.webtab6_URL));
tab7Args.putString("tabURL", getString(R.string.webtab7_URL));
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab1_name)),
MyWebviewFragment.class, tab1Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab2_name)),
MyWebviewFragment.class, tab2Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab3_name)),
MyWebviewFragment.class, tab3Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab4_name)),
MyWebviewFragment.class, tab4Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab5_name)),
MyWebviewFragment.class, tab5Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab6_name)),
MyWebviewFragment.class, tab6Args);
mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab7_name)),
MyWebviewFragment.class, tab7Args);
if (savedInstanceState != null) {
Log.i(tag,"onCreate: savedInstanceState: tab = " + savedInstanceState.getInt("tab", 0));
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}
Log.i(tag,"***** Exiting onCreate *****");
}
public boolean isOnline() {
Log.i(tag,"isOnline");
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
Log.i(tag,"isOnline: returning true");
return true;
}
Log.i(tag,"isOnline: returning false");
return false;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i(tag,"onSaveInstanceState: tab = " + getActionBar().getSelectedNavigationIndex());
outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
Log.i(tag,"***** Exiting onSaveInstanceState *****");
}
/**
* TabsAdapater class
*/
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener{
final static private String tag = TabsAdapter.class.getSimpleName();
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
Log.i(tag,"TabsAdapter: constructor");
mContext = activity;
mActionBar = ((SherlockFragmentActivity) activity).getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
Log.i(tag,"***** Exiting TabsAdapter: constructor *****");
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
Log.i(tag,"addTab");
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
Log.i(tag,"***** Exiting addTab *****");
}
@Override
public int getItemPosition(Object object)
{
Log.i(tag,"getItemPosition");
return PagerAdapter.POSITION_UNCHANGED;
}
@Override
public int getCount()
{
//Log.i(tag,"getCount");
int iCount = mTabs.size();
//Log.i(tag,"***** Exiting getCount *****");
return iCount;
}
@Override
public Fragment getItem(int position)
{
Log.i(tag,"getItem: " + position);
TabInfo info = mTabs.get(position);
Fragment frag = Fragment.instantiate(mContext, info.clss.getName(), info.args);
Log.i(tag,"***** Exiting getItem: " + position + " *****");
return frag;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
//Log.i(tag,"onPageScrolled: " + position);
}
@Override
public void onPageSelected(int position)
{
Log.i(tag,"onPageSelected: " + position);
mActionBar.setSelectedNavigationItem(position);
Log.i(tag,"***** Exiting onPageSelected *****");
}
@Override
public void onPageScrollStateChanged(int state)
{
//Log.i(tag,"onPageScrollStateChanged");
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
Log.i(tag,"onTabSelected: " + tab.getPosition());
Object tabTag = tab.getTag();
int numTabs = mTabs.size();
for (int i=0; i<numTabs; i++) {
if (mTabs.get(i) == tabTag) {
mViewPager.setCurrentItem(i);
}
}
Log.i(tag,"***** onTabSelected: " + tab.getPosition() + " *****");
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
{
Log.i(tag,"onTabUnselected: " +tab.getPosition());
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
{
Log.i(tag,"onTabRelected: " +tab.getPosition());
}
}
}
И код для фрагмента:
package com.mobilityinitiative.synergyworldwide;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnKeyListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
public class MyWebviewFragment extends SherlockFragment
{
final static private String tag = MyWebviewFragment.class.getSimpleName();
String mTabURL;
private WebView mWebView = null;
static final int REFRESH_ID = Menu.FIRST;
private ProgressDialog spinnerDlg;
/**
* When creating, retrieve this instance's number from its arguments.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(tag,"onCreate");
super.onCreate(savedInstanceState);
// Tell the framework to try to keep this fragment around
// during a configuration change.
setRetainInstance(true);
mTabURL = getArguments() != null ? getArguments().getString("tabURL") : "http://www.google.com";
Log.i(tag,"***** Exiting onCreate: URL = " + mTabURL + " *****");
}
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.i(tag,"onCreateView");
// Create view object to return
View v = inflater.inflate(R.layout.webview_layout, container, false);
// Check to see if it has been saved and restore it if true
if(savedInstanceState != null)
{
Log.i(tag,"savedInstance != null in onCreateView - attempting to restore view");
if (savedInstanceState.isEmpty())
Log.i(tag, "Can't restore state because bundle is empty.");
else
{
mWebView = ((WebView)v.findViewById(R.id.webview_fragment));
if(mWebView.restoreState(savedInstanceState) == null)
{
Log.i(tag, "Restoring state FAILED!");
}
else
{
Log.i(tag, "*!*!*!*!*!*! Restoring state succeeded. *!*!*!*!*!*!");
initWebView();
}
}
}
else
{
Log.i(tag,"savedInstance == null in onCreateView - creating new webview");
// Load web page
mWebView = (WebView)v.findViewById(R.id.webview_fragment);
Log.i(tag, ">>>>>> Calling initWebView on NEW tab <<<<<");
initWebView();
mWebView.loadUrl(mTabURL);
}
Log.i(tag, "***** Exiting onCreateView *****");
return v;
}
void initWebView()
{
Log.i(tag, "initWebView");
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setOnKeyListener(new OnKeyListener(){
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return false;
}
});
// Used to be in new creation
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.getSettings().setPluginsEnabled(true);
mWebView.getSettings().setBuiltInZoomControls(false);
mWebView.getSettings().setSupportZoom(false);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setDomStorageEnabled(true);
Log.i(tag, "***** Exit initWebView *****");
}
@Override
public void onSaveInstanceState(Bundle outState)
{
Log.i(tag,"onSaveInstanceState");
if(mWebView != null)
{
if( mWebView.saveState(outState) == null)
Log.i(tag,"Saving state FAILED!");
else
Log.i(tag, "Saving state succeeded.");
}
else
Log.i(tag, "No webview to save in onSaveInstanceState");
Log.i(tag,"***** Exiting onSaveInstanceState *****");
}
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
Log.i(tag,"onActivityCreated");
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
Log.i(tag,"***** Exiting onActivityCreated *****");
}
@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.i(tag,"onCreateOptionsMenu");
Log.i(tag,"onCreateOptionsMenu - menu loaded: " + mTabURL);
menu.add(Menu.NONE, REFRESH_ID, 0, getString(R.string.refresh_string))
.setIcon(R.drawable.ic_action_refresh)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
Log.i(tag,"***** Exiting onCreateOptionsMenu *****");
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
Log.i(tag,"onOptionsItemSelected");
boolean refreshItem = false;
switch (item.getItemId()) {
case REFRESH_ID:
if(mWebView != null)
mWebView.reload();
refreshItem = true;
default:
refreshItem = super.onOptionsItemSelected(item);
}
return refreshItem;
}
@Override
public void onDestroy()
{
Log.i(tag,"onDestroy");
super.onDestroy();
Log.i(tag,"***** Exiting onDestroy *****");
}
@Override
public void onDestroyView()
{
Log.i(tag,"onDestroyView");
super.onDestroyView();
Log.i(tag,"***** Exiting onDestroyView *****");
}
@Override
public void onPause()
{
Log.i(tag,"onPause");
super.onPause();
mWebView.onPause();
Log.i(tag,"***** Exiting onPause *****");
}
@Override
public void onResume()
{
Log.i(tag,"onResume");
super.onResume();
mWebView.onResume();
Log.i(tag,"***** Exiting onResume *****");
}
public boolean isOnline() {
Log.i(tag,"isOnline");
ConnectivityManager cm =
(ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
Log.i(tag,"***** Exiting isOnline: returning true *****");
return true;
}
Log.i(tag,"***** Exiting isOnline: returning false *****");
return false;
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
Log.i(tag,"onConfigurationChanged");
super.onConfigurationChanged(newConfig);
Log.i(tag,"***** Exiting onConfigurationChanged *****");
}
public class MyWebViewClient extends WebViewClient {
final private String tag = MyWebViewClient.class.getSimpleName();
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// YouTube video link
Log.i(tag, "shouldOverrideUrlLoading");
if (url.startsWith("http://youtu.be"))
{
String urlSubString = url.substring("http://youtu.be/".length());
String newURL = String.format("http://www.youtube.com/v/%s", urlSubString);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(newURL)));
return (true);
}
Log.i(tag, "***** Exiting shouldOverrideUrlLoading *****");
return (false);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//Log.i(tag, "onPageStarted");
if(spinnerDlg == null)
{
spinnerDlg = new ProgressDialog(getActivity());
spinnerDlg.setMessage("Loading....");
spinnerDlg.show();
}
//Log.i(tag, "***** Exiting onPageStarted *****");
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//Log.i(tag, "onPageFinished");
if(spinnerDlg != null)
{
spinnerDlg.dismiss();
}
spinnerDlg = null;
//Log.i(tag, "***** Exiting onPageFinished *****");
}
/* (non-Javadoc)
* @see android.webkit.WebViewClient#onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String)
*/
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl)
{
Log.i(tag,"onReceivedError - Error Code: " + errorCode + " Error Description: " + description + " Failing URL: " + failingUrl);
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
}
Как я уже сказал, я в полной растерянности. Я уверен, что либо неправильно сохраняю информацию, либо восстанавливаю ее правильно, но не могу понять.
Заранее спасибо всем, кто хочет разобраться в этом.