H5遊戲微端開發(三):app啓動流程

寫在前面

這篇文章主要是梳理H5遊戲微端app的啓動流程,然後解決這個流程中出現的問題,如網絡檢測斷網或訪問出錯處理



App啓動流程

個人認爲一個H5遊戲微端app的啓動流程應該是這樣的:

Created with Raphaël 2.2.0遊戲啓動頁檢測聯網是否聯網?訪問遊戲主頁是否訪問成功?進入遊戲顯示錯誤頁面解決網絡問題yesnoyesno


自定義html

在Android Studio工程新建assets目錄,添加兩個html文件:啓動頁(index.html)錯誤頁(error.html)

啓動頁:遊戲開始時顯示,可以在這裏顯示公司logp動畫,結束後正式訪問H5遊戲首頁。

錯誤頁:用於訪問H5遊戲首頁失敗,返回404或500錯誤時顯示。

webview加載html代碼:

final String INDEX_URL = "file:///android_asset/index.html";
WebViewCacheInterceptorInst.getInstance().loadUrl(mWebView, INDEX_URL);

注意,因爲我們用了CacheWebView第三方庫了,所以用WebViewCacheInterceptorInst.getInstance().loadUr()代替mWebView.loadUrl()方法;



檢測聯網

  • 定義一個廣播類NetStateReceiver繼承BroadcastReceiver,並且重寫onReceive方法,onReceive方法中就是我們想要廣播接收器收到廣播之後需要處理的操作。
@Override
public void onReceive(Context context, Intent intent){
    // 檢測網絡是否連通
    checkNetwork(context);
}
  • 對廣播進行註冊:在MainActivity進行註冊,並監聽網絡變化。
// MainActivity.java

private NetStateReceiver receiver = new NetStateReceiver();

IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(receiver, filter);
  • 如果網絡正常,那麼直接下一個流程,訪問遊戲主頁。否則的話彈窗提示。問題在於當NetStateReceiver檢測到網絡正常時,如何跟MainActivity通信。在NetStateReceiver中聲明接口NetworkObserver,然後MainActivity實現該接口,並把自身傳入NetStateReceiver作爲一個類成員變量,等到檢測網絡正常時調用對應方法。
// NetStateReceiver.java

public interface NetworkObserver{
    public void networkSuccess();
    public void networkFail();
}

public void setNetworkObserver(NetworkObserver observer) {
    this.observer = observer;
}
// MainActivity.java

public class MainActivity extends AppCompatActivity implements NetStateReceiver.NetworkObserver {
    private NetStateReceiver receiver = new NetStateReceiver();

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 將自身傳入到NetStateReceiver中
        receiver.setNetworkObserver(this);
    }
}
// NetStateReceiver.java

// 檢測網絡,成功or失敗調用MainActivity對應的方法
public void checkNetwork(Context context){
    ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isAvailable()){
        Toast.makeText(context, "網絡連接成功", Toast.LENGTH_SHORT).show();
        closeDialog();
        this.observer.networkSuccess();
        LogUtil.d("network succuess");
    }else{
        showDialog(context);
        this.observer.networkFail();
        LogUtil.d("network fail");
    }
}


Webview處理404、500、斷網

加載網頁的過程中,可能會因爲網絡問題出現各種錯誤情況,這時候會顯示默認的錯誤頁面。

瞭解WebView的各種錯誤情況,既可以定製錯誤頁面,也可以根據不同的錯誤情況進行處理。


WebView監聽錯誤的方法

  • onReceiveError

onReceiveError是WebViewClient提供的方法,用於網頁產生錯誤時進行回調處理。

簡單來說,onReceiveError只有在遇到不可用的(unrecoverable)錯誤時纔會被調用。

不可用的情況包括:

1、沒有網絡連接

2、連接超時

3、找不到頁面

而下面的情況則不會被報告:

1、網頁內引用其他資源加載錯誤,比如圖片、css不可用

2、js執行錯誤

  • onReceivedHttpError

onReceivedHttpError也是WebViewClient提供的方法,主要是用於捕獲 Http Error (404、500)。


處理404、500

Android6.0以上可以重寫onReceivedHttpError方法捕獲http Error,而Android6.0以下訪問出錯時,是不會跑到這個函數的。

  • Android6.0以上版本:重寫onReceivedHttpError
mWebView.setWebViewClient(new WebViewClient(){
    @TargetApi(android.os.Build.VERSION_CODES.M)
    @Override
    public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
        super.onReceivedHttpError(view, request, errorResponse);
        // 這個方法在6.0纔出現
        int statusCode = errorResponse.getStatusCode();
        if (404 == statusCode || 500 == statusCode) {
            LogUtil.d("deal http error(android version above 6.0), statusCode = " + statusCode);
            showErrorPage();
        }
    }
}
  • Android6.0以下版本:通過獲取網頁的title,判斷是否爲系統默認的404頁面
mWebView.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
        // android 6.0 以下通過title獲取
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            if (title.contains("404") || title.contains("500") || title.contains("Error") || title.contains("找不到網頁") || title.contains("網頁無法打開")) {
                LogUtil.d("deal http error(android version below 6.0), title = " + title);
                showErrorPage();
            }
        }
    }
});

處理斷網和鏈接超時

  • Android6.0以上版本:
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
    super.onReceivedError(view, request, error);
    if (request.isForMainFrame()){  // 是否是爲 main frame創建
        LogUtil.d("onReceivedError (android version above 6.0), code = " + error.getErrorCode() + ", desc = " + error.getDescription());
        showErrorPage();
    }
}
  • Android6.0以下版本
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    super.onReceivedError(view, errorCode, description, failingUrl);
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        return;
    }
    LogUtil.d("onReceivedError (android version below 6.0), code = " + errorCode + ", desc = " + description);
    showErrorPage();
}


完整的Github工程:H5MicroClient

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章