我的应用程序可以使用 appcache 在线和离线运行。它还会在某一时刻在默认浏览器上打开一个链接。问题是当它离线加载时,链接到默认浏览器后无法重新打开应用程序。
这是我的代码:
public class MainActivity extends Activity
{
private WebView wv;
private ProgressBar progress;
private static String mycaturl="*url*";
private static String helpurl="*url*";
private static String fbackurl="*url*";
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);
if (reachable(this))
{
buildwv( savedInstanceState, WebSettings.LOAD_DEFAULT, mycaturl );
}
else
{
eolc( savedInstanceState );
}
}
@SuppressLint({ "SetJavaScriptEnabled" })
public void buildwv(Bundle sis, int load, String url)
{
if(reachable(this))
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
else
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
setContentView(R.layout.activity_main);
progress=(ProgressBar) findViewById(R.id.progress);
wv=(WebView) findViewById(R.id.wv);
wv.setWebViewClient( new wvc() );
wv.setHorizontalScrollBarEnabled(false);
WebSettings ws = wv.getSettings();
ws.setAppCacheMaxSize( 100 * 1024 * 1024 ); // 100MB
ws.setAppCachePath( this.getCacheDir().getAbsolutePath() );
ws.setAllowFileAccess( true );
ws.setAppCacheEnabled( true );
ws.setJavaScriptEnabled( true );
ws.setCacheMode(load);
if(sis==null)
{ wv.loadUrl(url); }
}
public void eolc(final Bundle sis)
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
AlertDialog.Builder ad = new AlertDialog.Builder( MainActivity.this );
ad.setTitle("Unreachable Host");
ad.setMessage("Host is unreachable. Load from cache or exit.");
ad.setIcon(R.drawable.tick);
ad.setCancelable(false);
ad.setPositiveButton( "Load from Cache", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
buildwv( sis, WebSettings.LOAD_CACHE_ELSE_NETWORK, mycaturl );
}
});
ad.setNeutralButton( "Help", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
buildwv( sis, WebSettings.LOAD_CACHE_ELSE_NETWORK, helpurl );
}
});
ad.setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
ad.create();
ad.show();
}
public void alertprep(String set)
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if( set=="def")
{
String a = "Connection Lost";
String b = "Connection to host was lost. Restart and load cache or exit.";
alert(a,b);
}
else if( set=="cac" )
{
String a = "Page Not Cached";
String b = "Page you're trying to view is not yet cached. Please visit help to learn how to cache.";
alert(a,b);
}
}
public void alert(String a,String b)
{
AlertDialog.Builder ad = new AlertDialog.Builder( MainActivity.this );
ad.setTitle(a);
ad.setMessage(b);
ad.setIcon(R.drawable.tick);
ad.setCancelable(false);
ad.setPositiveButton( "Restart", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity(i);
}
});
ad.setNeutralButton( "Help", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
wv.stopLoading();
wv.loadUrl( helpurl );
}
});
ad.setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
ad.create();
ad.show();
}
private class wvc extends WebViewClient
{
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
super.onPageStarted(view, url, favicon);
progress.setVisibility(View.VISIBLE);
if (url.contains(mycaturl))
{
WebSettings ws = wv.getSettings();
if ( !reachable(getApplicationContext()) )
{
if ( ws.getCacheMode() == WebSettings.LOAD_DEFAULT )
{
alertprep("def");
}
}
}
}
@Override
public void onPageFinished(WebView view, String url)
{
super.onPageFinished(view, url);
progress.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
super.onReceivedError(view, errorCode, description, failingUrl);
wv.loadUrl(helpurl);
WebSettings ws = wv.getSettings();
if ( ws.getCacheMode() == WebSettings.LOAD_DEFAULT )
{
alertprep("def");
}
else
{
alertprep("cac");
}
}
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url != null && url.contains("dgcrfdbck"))
{
jumptofback();
return true;
} else {
return false;
}
}
}
public void jumptofback()
{
wv.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(fbackurl)));
}
public static boolean reachable(Context context)
{
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo netInfo = connMgr.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
{
try
{
URL url = new URL(mycaturl);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(5000);
urlc.connect();
if (urlc.getResponseCode() == 200)
{ return true; } else { return false; }
}
catch (IOException e)
{ return false; }
}
else
{ return false; }
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onBackPressed ()
{
if (wv.isFocused() && wv.canGoBack())
{ wv.goBack(); } else { finish(); }
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.item1:
wv.loadUrl( helpurl );
break;
case R.id.item2:
jumptofback();
break;
case R.id.item3:
String currurl=wv.getUrl();
wv.loadUrl(currurl);
break;
case R.id.item4:
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
break;
case R.id.item5:
finish();
break;
default:
break;
}
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState )
{
super.onSaveInstanceState(outState);
wv.saveState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
wv.restoreState(savedInstanceState);
}
}
这是 logcat 中的错误部分:
09-30 18:25:04.375: D/AndroidRuntime(15930): Shutting down VM
09-30 18:25:04.375: W/dalvikvm(15930): threadid=1: thread exiting with uncaught exception (group=0x41b352a0)
09-30 18:25:04.380: E/AndroidRuntime(15930): FATAL EXCEPTION: main
09-30 18:25:04.380: E/AndroidRuntime(15930): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.msiecsapps.mycatlog/com.msiecsapps.mycatlog.MainActivity}: java.lang.NullPointerException
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.access$600(ActivityThread.java:140)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.os.Handler.dispatchMessage(Handler.java:99)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.os.Looper.loop(Looper.java:137)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.main(ActivityThread.java:4898)
09-30 18:25:04.380: E/AndroidRuntime(15930): at java.lang.reflect.Method.invokeNative(Native Method)
09-30 18:25:04.380: E/AndroidRuntime(15930): at java.lang.reflect.Method.invoke(Method.java:511)
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
09-30 18:25:04.380: E/AndroidRuntime(15930): at dalvik.system.NativeStart.main(Native Method)
09-30 18:25:04.380: E/AndroidRuntime(15930): Caused by: java.lang.NullPointerException
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.msiecsapps.mycatlog.MainActivity.onRestoreInstanceState(MainActivity.java:305)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.Activity.performRestoreInstanceState(Activity.java:944)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1134)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
09-30 18:25:04.380: E/AndroidRuntime(15930): ... 11 more
提前致谢。