Когда ActivityManager убивает приложение, я не могу восстановить приложение ViewPager с 7 вкладками, все WebViews во фрагментах - PullRequest
0 голосов
/ 13 марта 2012

У меня есть приложение 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);

    }
}
}

Как я уже сказал, я в полной растерянности. Я уверен, что либо неправильно сохраняю информацию, либо восстанавливаю ее правильно, но не могу понять.

Заранее спасибо всем, кто хочет разобраться в этом.

1 Ответ

0 голосов
/ 13 марта 2012

Почему бы вам не попробовать реализовать onLowMemory () .Я чувствую, что это будет вызвано до закрытия вашего приложения.может быть, вы можете сохранить состояние приложения и очистить его.

...