记一次与webview交互的封装

写与H5交互方法的activity,其中方法的传值只能有一个

public class RiskTestActivity extends HtmlActivity implements ReportBannerView {
  public static final String PRODUCT_ID = "extra.product_id";
  public static final String H5_PARAMETER = "webViewBackFlagNum";
  public static final String BANNER_TYPE = "banner_type";
  public static final String BANNER_REPORT_ID = "banner_report_id";
  public static final String BANNER_ID = "banner_id";
  public static final String BANNER_SOURCE = "banner_source";
  public static final int LIVT_TYPE = 2;

  private static final String APP_ID = BuildConfig.APP_ID;

  public static void loadUrl(Context context, String url) {
    Intent it = new Intent(context, RiskTestActivity.class);
    it.putExtra(EXTRA_URL, url);
    context.startActivity(it);
  }

  public static void loadUrlForNewTask(Context context, String url) {
    Intent it = new Intent(context, RiskTestActivity.class);
    it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    it.putExtra(EXTRA_URL, url);
    context.startActivity(it);
  }

  public static void loadUrlForBanner(Context context, String url, int bannerType, int source,
      long id) {
    Intent it = new Intent(context, RiskTestActivity.class);
    it.putExtra(EXTRA_URL, url);
    it.putExtra(BANNER_TYPE, bannerType);
    it.putExtra(BANNER_SOURCE, source);
    it.putExtra(BANNER_ID, id);
    context.startActivity(it);
  }

  public static void loadUrl(Context context, String url, String title) {
    Intent it = new Intent(context, RiskTestActivity.class);
    it.putExtra(EXTRA_URL, url);
    it.putExtra(EXTRA_TITLE, title);
    it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(it);
  }

  public static void loadUrlWithHeader(Context context, String url, String header) {
    Map<String, String> headers = new HashMap<>();
    headers.put("xtoken", header);
    headers.put(HeadInterceptor.CAANNELNAME, HeadInterceptor.CAANNELVALUE);
    headers.put(HeadInterceptor.CHANNELPWD, HeadInterceptor.CHANNELPWDVALUE);
    Intent it = new Intent(context, RiskTestActivity.class);
    it.putExtra(EXTRA_URL, url);
    it.putExtra(EXTRA_HEADERS, (Serializable) headers);
    context.startActivity(it);
  }

  public static void loadUrl(Context context, String data, String mimeType, String encoding) {
    Intent it = new Intent(context, RiskTestActivity.class);
    it.putExtra(EXTRA_DATA, data);
    it.putExtra(EXTRA_MIME_TYPE, mimeType);
    it.putExtra(EXTRA_ENCODING, encoding);
    context.startActivity(it);
  }

  public static void loadUrl(Context context, String baseUrl, String data, String mimeType,
      String encoding, String historyUrl, Class targetClass) {
    Intent it = new Intent(context, targetClass);
    it.putExtra(EXTRA_BASE_URL, baseUrl);
    it.putExtra(EXTRA_DATA, data);
    it.putExtra(EXTRA_MIME_TYPE, mimeType);
    it.putExtra(EXTRA_ENCODING, encoding);
    it.putExtra(EXTRA_HISTORY_URL, historyUrl);
    context.startActivity(it);
  }

  private String productId;
  private boolean canGoBack;
  @Inject ReportBannerPresenter presenter;
  //上报Id
  private BannerId bannerReportId;
  private int bannerType;
  private int bannerIntentSource;
  //banner入库Id
  private long bannerId;

  @Override protected void onInit(Bundle savedInstanceState) {
    super.onInit(savedInstanceState);
    DaggerLoanConponent.builder()
        .appComponent(Injector.obtain(getApplication()))
        .build()
        .inject(this);
    delegatePresenter(presenter, this);
    setDisplayDown(false);
    productId = getIntent().getStringExtra(PRODUCT_ID);
    bannerType = getIntent().getIntExtra(BANNER_TYPE, 0);
    bannerIntentSource = getIntent().getIntExtra(BANNER_SOURCE, 0);
    bannerId = getIntent().getLongExtra(BANNER_ID, 0l);
    if (bannerType == LIVT_TYPE) {
      presenter.reportStartBanner(bannerIntentSource, this, bannerId,
          transformType(bannerIntentSource));
    }
    htmlView.setWebViewClient(new MyWebViewClite());
    htmlView.setWebChromeClient(new MyWebChromeClient());
    register();
  }

  @Override protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelable(BANNER_REPORT_ID, bannerReportId);
    outState.putString(PRODUCT_ID, productId);
    outState.getInt(BANNER_TYPE, bannerType);
    outState.putInt(BANNER_SOURCE, bannerIntentSource);
    outState.putLong(BANNER_ID, bannerId);
  }

  @Override protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    bannerReportId = savedInstanceState.getParcelable(BANNER_REPORT_ID);
    productId = savedInstanceState.getString(PRODUCT_ID);
    bannerType = savedInstanceState.getInt(BANNER_TYPE);
    bannerIntentSource = savedInstanceState.getInt(BANNER_SOURCE);
    bannerId = savedInstanceState.getLong(BANNER_ID);
  }

  public void register() {
    htmlView.registNativeModule(new NativeModule() {
      @Override public String getName() {
        return "fiveMine";
      }

      @ModuleMethod(name = "setUserName")
      public void setUserName() {
        navigator.navigateToUserName(RiskTestActivity.this);
      }

      @ModuleMethod(name = "userCertification")
      public void userCertification() {
        navigator.navigateToIdcard(RiskTestActivity.this);
      }

      @ModuleMethod(name = "userRate")
      public void userRate() {
        if (accountManager.isIdentityAuthenticated()) {
          navigator.navigateToRiskTest(RiskTestActivity.this,
              Flavor.h5Url(RiskTestActivity.this) + Config.RISK_TEST + "1",
              accountManager.peekAuthToken(), productId);
          finish();
        } else {
          DialogUtils.showIdentyDialog(RiskTestActivity.this, "实名认证后可测评",
              new NotificationDialog.PositiveClickListener() {
                @Override public void onPositiveClickListener(View v) {
                  navigator.navigateToIdcard(RiskTestActivity.this);
                }
              });
        }
      }

      @ModuleMethod(name = "userShare")
      public void userShare() {
        if (checkIdentity("分享")) {
          SharePopwindow popwindow = new SharePopwindow(RiskTestActivity.this, accountManager);
          popwindow.showPop();
        }
      }

      @ModuleMethod(name = "bindBank")
      public void bindBank() {
        if (checkIdentity("绑卡")) {
          navigator.navigateToBankList(RiskTestActivity.this);
        }
      }

      @ModuleMethod(name = "contactInfo")
      public void contactInfo() {
        if (checkIdentity("添加")) {
          navigator.navigateToContacts(RiskTestActivity.this);
        }
      }

      @ModuleMethod(name = "onlineBook")
      public void onlineBook() {
        navigator.navigateToHome(RiskTestActivity.this, 1);
      }

      @ModuleMethod(name = "onlineSignature")
      public void onlineSignature() {
        navigator.navigateToHome(RiskTestActivity.this, 1);
      }

      @ModuleMethod(name = "callPhone")
      public void callPhone(String phone) {
        navigator.navigateToCall(RiskTestActivity.this, phone);
      }

      @ModuleMethod(name = "openLink")
      public void openLink(String url) {
        if (!Strings.isBlank(url)) {
          String linkUrl = url.contains("http") ? url : Flavor.h5Url(RiskTestActivity.this) + url;
          RiskTestActivity.loadUrl(RiskTestActivity.this, linkUrl);
        }
      }

      @ModuleMethod(name = "ratingJump")
      public void ratingJump(String code) {
        //if (code.equals("2")||code.equals("4")) {
        //  navigator.navigateToProductDetail(RiskTestActivity.this,
        //      Strings.isBlank(productId) ? 0 : Integer.parseInt(productId),code.equals("2")? 0:1);
        //}
        RiskTestActivity.this.finish();
      }


      @ModuleMethod(name = "showIdentityDialog")
      public void showIdentityDialog(String tips) {
        checkIdentity(tips, true);
      }

      @ModuleMethod(name = "shareWX")
      public void shareWX( String json) {
//        String webUrl, String title, String content, Base64 bitmap


        if (!Strings.isBlank(json)) {
          String webUrl=null;
          String title=null;
          String content = null;
          String bitmap=null;
          try {
            JSONObject jsonObject = new JSONObject(json);
            webUrl = jsonObject.getString("webUrl");
            title = jsonObject.getString("title");
            content = jsonObject.getString("content");
            bitmap = jsonObject.getString("bitmap");
            if (Strings.isBlank(webUrl)) {
              return;
            }
            SharePopwindow popwindow = new SharePopwindow(RiskTestActivity.this,RiskTestActivity.this, accountManager,APP_ID,webUrl,title,content,WXShareUtils.stringtoBitmap(bitmap));
            popwindow.showPop();
//            WXShareUtils.shareWeb(RiskTestActivity.this, APP_ID,
//                    webUrl, title, content,
//                    WXShareUtils.stringtoBitmap(bitmap));
          } catch (JSONException e) {
            e.printStackTrace();
          }


        }

      }

      @ModuleMethod(name = "openLive")
      public void openLive(String json) {
        if (!Strings.isBlank(json)) {
          int id;
          String url;
          try {
            JSONObject jsonObject = new JSONObject(json);
            id = jsonObject.getInt("idNum");
            url = jsonObject.getString("url");
            if (Strings.isBlank(url)) {
              return;
            }
            url = url.contains("http") ? url : Flavor.h5Url(RiskTestActivity.this) + url;
            RiskTestActivity.loadUrlForBanner(RiskTestActivity.this, url,
                RiskTestActivity.LIVT_TYPE,
                Constants.LIVE_LIST, id);
          } catch (JSONException e) {
            e.printStackTrace();
          }
        }
      }
    });
  }

  @Override protected void onDestroy() {
    if (htmlView != null) {
      ViewGroup parent = (ViewGroup) htmlView.getParent();
      if (parent != null) {
        parent.removeView(htmlView);
      }
      htmlView.setWebChromeClient(new WebChromeClient());
      htmlView.removeAllViews();
      htmlView.destroy();
    }
    super.onDestroy();
  }

  @Override protected void onRestart() {
    super.onRestart();
    if (htmlView != null) {
      htmlView.reload();
    }
  }

  @Override public void onResume() {
    super.onResume();
  }

  @Override protected void onHomeAsUp() {
    if (canGoBack) {
      if (bannerType == LIVT_TYPE && bannerReportId != null) {
        presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
        return;
      }
      finish();
      return;
    }

    if (bannerType == LIVT_TYPE && !htmlView.canGoBack() && bannerReportId != null) {
      presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
      return;
    }
    if (htmlView.canGoBack()) {
      htmlView.goBack();
      return;
    }
    super.onHomeAsUp();
  }

  @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
      if (canGoBack) {
        if (bannerType == LIVT_TYPE && bannerReportId != null) {
          presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
          return true;
        }
        finish();
        return true;
      }

      if (bannerType == LIVT_TYPE && !htmlView.canGoBack() && bannerReportId != null) {
        presenter.reportEndBanner(bannerIntentSource, this, bannerReportId);
        return true;
      }
      if (htmlView.canGoBack()) {
        htmlView.goBack();
        return true;
      }
    }
    return super.onKeyDown(keyCode, event);
  }

  @Override public void showId(BannerId bannerId) {
    this.bannerReportId = bannerId;
    this.bannerReportId.type = transformType(bannerIntentSource);
  }

  @Override public void modifySuccess() {
    finish();
  }

  @Override public void showLoading() {
    showLoadingDialog();
  }

  @Override public void hideLoading() {
    hideLoadingDialog();
  }

  private class MyWebViewClite extends SampleWebViewClient {

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
      final Uri uri = request.getUrl();
      if (uri.toString().startsWith("tel:")) {
        //Handle telephony Urls
        navigator.navigateToCall(RiskTestActivity.this, uri.toString().substring(4));
        return true;
      }
      return super.shouldOverrideUrlLoading(view, request);
    }

    @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
      if (url.startsWith("tel:")) {
        //Handle telephony Urls
        navigator.navigateToCall(RiskTestActivity.this, url.substring(4));
        return true;
      }
      return super.shouldOverrideUrlLoading(view, url);
    }

    @Override public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      if (htmlView != null && isLoadFinish) {
        htmlView.invokeJsModule("", "appCallBack");
      }
      if(!Strings.isBlank(url)){
        String parameter = Uri.parse(url).getQueryParameter(H5_PARAMETER);
        canGoBack = parameter != null && parameter.equals("1");
      }
    }
  }

  private class MyWebChromeClient extends WebChromeClient {

    private CustomViewCallback mCustomViewCallback;
    //  横屏时,显示视频的view
    private View mCustomView;

    // 点击全屏按钮时,调用的方法
    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
      super.onShowCustomView(view, callback);

      //如果view 已经存在,则隐藏
      if (mCustomView != null) {
        callback.onCustomViewHidden();
        return;
      }

      mCustomView = view;
      mCustomView.setVisibility(View.VISIBLE);
      mCustomViewCallback = callback;
      videoLayout.addView(mCustomView);
      videoLayout.setVisibility(View.VISIBLE);
      videoLayout.bringToFront();

      //设置横屏
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    // 取消全屏调用的方法
    @Override
    public void onHideCustomView() {
      super.onHideCustomView();
      if (mCustomView == null) {
        return;
      }
      mCustomView.setVisibility(View.GONE);
      videoLayout.removeView(mCustomView);
      mCustomView = null;
      videoLayout.setVisibility(View.GONE);
      try {
        mCustomViewCallback.onCustomViewHidden();
      } catch (Exception e) {
      }
      setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏
    }

    @Override public void onGeolocationPermissionsShowPrompt(String origin,
        GeolocationPermissions.Callback callback) {
      callback.invoke(origin, true, false);
      super.onGeolocationPermissionsShowPrompt(origin, callback);
    }

    @Override public void onReceivedTitle(WebView view, String t) {
      super.onReceivedTitle(view, t);
      if (!Strings.isBlank(t) && !t.contains("mintrust")) {
        title = t;
        setToolbarTitle(t);
      }
    }
  }

  /**
   * 横竖屏切换监听
   */
  @Override
  public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);
    switch (config.orientation) {
      case Configuration.ORIENTATION_LANDSCAPE:
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        break;
      case Configuration.ORIENTATION_PORTRAIT:
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        break;
        default:
    }
  }

  private int transformType(int source) {
    int type = 0;
    switch (source) {
      case 5:
        type = 1;
        break;
      case 6:
        type = 2;
        break;
      case 7:
        type = 3;
        break;
      case 8:
        type = 4;
        break;
        default:
    }
    return type;
  }
}

自定义注解

@Target(METHOD) @Retention(RUNTIME)
@Documented
public @interface ModuleMethod {
  String name();
}

 HTMLActivity

public class HtmlActivity extends BaseActivity {

  public static final String EXTRA_TITLE = "extra.html.title";
  public static final String EXTRA_URL = "extra.html.url";
  public static final String EXTRA_FIRST_URL = "extra.html.first.url";
  public static final String EXTRA_DATA = "extra.html.data";
  public static final String EXTRA_MIME_TYPE = "extra.html.mime_type";
  public static final String EXTRA_ENCODING = "extra.html.encoding";
  public static final String EXTRA_BASE_URL = "extra.html.base_url";
  public static final String EXTRA_HISTORY_URL = "extra.html.history_url";
  public static final String EXTRA_HEADERS = "extra.html.headers";
  private static final int FILE_CHOOSER_RESULT_CODE = 0x21;

  @BindView(R.id.htmlview) protected CustomHtmlView htmlView;
  @BindView(R.id.fl_video) protected FrameLayout videoLayout;
  @BindView(R.id.error) protected TextView tvError;
  @BindView(R.id.container_tool_bar) protected RelativeLayout layoutTitle;
  @BindView(R.id.tv_title_html) protected TextView tvTitle;

  public String title;
  private String url;
  private String firstUrl;
  private String currentUrl;
  protected String data;
  protected String mimeType;
  protected String encoding;
  private String baseUrl;
  private String historyUrl;
  private Map<String, String> headers;
  private WebViewClient webViewClient;
  protected boolean isError, isLoadFinish = false;
  private String errorUrl;
  private FileChooserModule.FileChoooserCallback fileChoooserCallback;

  public static void loadUrl(Context context, String url) {
    Intent it = new Intent(context, HtmlActivity.class);
    it.putExtra(EXTRA_URL, url);
    context.startActivity(it);
  }

  @Override protected int layoutResId() {
    return R.layout.activity_html;
  }

  @Override protected void onInit(Bundle savedInstanceState) {
    DaggerEmptyComponent.builder()
        .appComponent(Injector.obtain(getApplication()))
        .build()
        .inject(this);

    isError = false;
    errorUrl = null;
    firstUrl = "";
    currentUrl = "";
    htmlView.setWebViewClient(new SampleWebViewClient());
    htmlView.setWebChromeClient(new GpsChromeClient());
    //htmlView.registNativeModule(fileChooserModule);
    htmlView.registNativeModule(new HtmlModule());
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      WebView.setWebContentsDebuggingEnabled(true);
    }

    if (savedInstanceState != null) {
      title = savedInstanceState.getString(EXTRA_TITLE);
      firstUrl = savedInstanceState.getString(EXTRA_FIRST_URL);
      url = savedInstanceState.getString(EXTRA_URL);
      data = savedInstanceState.getString(EXTRA_DATA);
      mimeType = savedInstanceState.getString(EXTRA_MIME_TYPE);
      encoding = savedInstanceState.getString(EXTRA_ENCODING);
      baseUrl = savedInstanceState.getString(EXTRA_BASE_URL);
      historyUrl = savedInstanceState.getString(EXTRA_HISTORY_URL);

      //noinspection unchecked
      headers = (Map<String, String>) savedInstanceState.getSerializable(EXTRA_HEADERS);
    } else {
      Intent it = getIntent();
      title = it.getStringExtra(EXTRA_TITLE);
      url = it.getStringExtra(EXTRA_URL);
      data = it.getStringExtra(EXTRA_DATA);
      mimeType = it.getStringExtra(EXTRA_MIME_TYPE);
      encoding = it.getStringExtra(EXTRA_ENCODING);
      baseUrl = it.getStringExtra(EXTRA_BASE_URL);
      historyUrl = it.getStringExtra(EXTRA_HISTORY_URL);
      firstUrl = url;
      //noinspection unchecked
      headers = (Map<String, String>) it.getSerializableExtra(EXTRA_HEADERS);
    }
    Timber.i("Load url: " + url);

    if (url != null) {
      if (headers != null) {
        htmlView.loadUrl(url, headers);
      } else {
        htmlView.loadUrl(url);
      }
    } else {
      if (baseUrl != null) {
        htmlView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
      } else if (data != null) {
        htmlView.loadData(data, mimeType, encoding);
      }
    }
    if (!TextUtils.isEmpty(title)) {
      setDisplayHomeAsUp(true);
      setToolbarTitle(title);
    }
  }

  @Override protected void onResume() {
    super.onResume();
    htmlView.onResume();
  }

  @Override protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(EXTRA_TITLE, title);
    outState.putString(EXTRA_URL, url);
    outState.putString(EXTRA_FIRST_URL, firstUrl);
    outState.putString(EXTRA_DATA, data);
    outState.putString(EXTRA_MIME_TYPE, mimeType);
    outState.putString(EXTRA_ENCODING, encoding);
    outState.putString(EXTRA_BASE_URL, baseUrl);
    outState.putString(EXTRA_HEADERS, historyUrl);
    outState.putSerializable(EXTRA_HEADERS, (Serializable) headers);
  }

  @OnClick(R.id.tv_back_html) void back() {
    onHomeAsUp();
  }

  @OnClick(R.id.img_close) void close() {
    finish();
  }

  @Override protected void onDestroy() {
    if (null != htmlView) {
      ViewGroup viewGroup = (ViewGroup) htmlView.getParent();
      if (null != viewGroup) {
        viewGroup.removeView(htmlView);
      }
    }
    htmlView.setWebChromeClient(new WebChromeClient());
    htmlView.removeAllViews();
    htmlView.destroy();
    super.onDestroy();
  }

  public void setWebViewClient(WebViewClient webViewClient) {
    this.webViewClient = webViewClient;
    if (htmlView != null) {
      htmlView.setWebViewClient(new SampleWebViewClient());
    }
  }

  public class SampleWebViewClient extends WebViewClient {

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
      final Uri uri = request.getUrl();
      if (uri.toString().startsWith("http") || uri.toString().startsWith("https")) {
        return super.shouldOverrideUrlLoading(view, request);
      }
      navigator.navigateToBrowser(HtmlActivity.this, uri.toString());
      return true;
    }

    @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
      if (url.startsWith("http") || url.startsWith("https")) {
        return super.shouldOverrideUrlLoading(view, url);
      }
      navigator.navigateToBrowser(HtmlActivity.this, url);
      return true;
    }

    @Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
      super.onPageStarted(view, url, favicon);
      currentUrl = url;
      showLoadingDialog();
      if (errorUrl == null || !url.equals(errorUrl)) {
        isError = false;
      }
      if (webViewClient != null) {
        webViewClient.onPageStarted(view, url, favicon);
      }
    }

    @SuppressWarnings("deprecation") @Override
    public void onReceivedError(WebView view, int errorCode, String description,
        String failingUrl) {
      super.onReceivedError(view, errorCode, description, failingUrl);

      if (errorCode == 612 || errorCode == 401) {
        navigator.navigateToLogin(getApplication(), true);
        finish();
      }
      isError = true;
      errorUrl = failingUrl;
      Timber.e("Html Error:" + errorCode + "----" + description);
      if (webViewClient != null) {
        webViewClient.onReceivedError(view, errorCode, description, failingUrl);
      }
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
      super.onReceivedSslError(view, handler, error);
      if (webViewClient != null) {
        webViewClient.onReceivedSslError(view, handler, error);
      }
    }

    @Override public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      hideLoadingDialog();
      if (null != tvError && null != htmlView) {
        if (isError) {
          isLoadFinish = false;
          tvError.setVisibility(View.VISIBLE);
          htmlView.setVisibility(View.GONE);
        } else {
          isLoadFinish = true;
          tvError.setVisibility(View.GONE);
          htmlView.setVisibility(View.VISIBLE);
        }
      }

      if (webViewClient != null) {
        webViewClient.onPageFinished(view, url);
      }
    }
  }

  @OnClick(R.id.error) protected void Onclick() {
    errorUrl = "";
    tvError.setVisibility(View.GONE);
    htmlView.reload();
  }

  @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && htmlView.canGoBack()) {
      htmlView.goBack();
      return true;
    }
    return super.onKeyDown(keyCode, event);
  }

  @Override protected void onHomeAsUp() {
    if (htmlView.canGoBack()) {
      htmlView.goBack();
    } else {
      finish();
    }
  }

  private void openImageChooserActivity() {
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.addCategory(Intent.CATEGORY_OPENABLE);
    i.setType("image/*");
    startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
  }

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //htmlView.onActivityResult(requestCode, resultCode, data);
  }

  FileChooserModule fileChooserModule = new FileChooserModule() {
    @Override public void onOpenFileChooser(FileChooserModule.FileChooserParams fileChooserParams,
        FileChooserModule.FileChoooserCallback mediaPickerCallback) {
      fileChoooserCallback = mediaPickerCallback;
      openImageChooserActivity();
    }

    @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (fileChoooserCallback == null) {
        return;
      }

      Uri[] results = null;
      if (requestCode == FILE_CHOOSER_RESULT_CODE && resultCode == Activity.RESULT_OK) {
        if (data != null) {
          String dataString = data.getDataString();
          ClipData clipData = null;
          if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            clipData = data.getClipData();
          }
          if (clipData != null) {
            results = new Uri[clipData.getItemCount()];
            for (int i = 0; i < clipData.getItemCount(); i++) {
              ClipData.Item item = clipData.getItemAt(i);
              results[i] = item.getUri();
            }
          }
          if (dataString != null) {
              results = new Uri[] { Uri.parse(dataString) };
          }
        }

        fileChoooserCallback.invoke(results);
        fileChoooserCallback = null;
      }
    }
  };

  /**
   * h5定位的支持
   */
  final class GpsChromeClient extends WebChromeClient {
    @Override public void onGeolocationPermissionsShowPrompt(String origin,
        GeolocationPermissions.Callback callback) {
      callback.invoke(origin, true, false);
      super.onGeolocationPermissionsShowPrompt(origin, callback);
    }

    @Override public void onReceivedTitle(WebView view, String title) {
      if (!TextUtils.isEmpty(title) && !title.contains("mintrust")) {
        HtmlActivity.this.title = title;
        setToolbarTitle(title);
      }
    }
  }

  public class HtmlModule extends NativeModule {

    @Override public String getName() {
      return "fiveMine";
    }

    @ModuleMethod(name = "goLogin")
    public void goLogin() {
      accountManager.clear();
      activityManager.clear();
      navigator.navigateToLogin(HtmlActivity.this, true);
    }

    @ModuleMethod(name = "openLink")
    public void openLink(String url) {
      if (!Strings.isBlank(url)) {
        String linkUrl = url.contains("http") ? url : Flavor.h5Url(HtmlActivity.this) + url;
        RiskTestActivity.loadUrl(HtmlActivity.this, linkUrl);
      }
    }

    @ModuleMethod(name = "showIdentityDialog")
    public void showIdentityDialog(String tips) {
      checkIdentity(tips, true);
    }

    @ModuleMethod(name = "callPhone")
    public void callPhone(String phone) {
      navigator.navigateToCall(HtmlActivity.this, phone);
    }
  }
}

CustomeHTMLView

public class CustomHtmlView extends BridgeWebView {
  private WebSettings webSettings;

  public CustomHtmlView(Context context) {
    this(context, null);
  }

  @SuppressLint("SetJavaScriptEnabled") public CustomHtmlView(Context context, AttributeSet attrs) {
    super(context, attrs);
    webSettings = getSettings();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      webSettings.setLoadsImagesAutomatically(true);
    } else {
      webSettings.setLoadsImagesAutomatically(false);
    }
    webSettings.setJavaScriptEnabled(true);
    webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

    webSettings.setDomStorageEnabled(true);
    webSettings.setDatabaseEnabled(true);
    webSettings.setAppCacheEnabled(true);

    webSettings.setAllowContentAccess(true);
    webSettings.setAllowFileAccess(true);
    //播放视频准备
    webSettings.setLoadWithOverviewMode(true);
    webSettings.setUseWideViewPort(true);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      webSettings.setAllowFileAccessFromFileURLs(true);
    }

    webSettings.setSupportZoom(false);
    webSettings.setDisplayZoomControls(false);

    webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
    webSettings.setGeolocationEnabled(true);
    webSettings.setSupportMultipleWindows(true);
    webSettings.setSaveFormData(true);
  }

  @Override public void setWebViewClient(WebViewClient client) {
    super.setWebViewClient(new WebViewClientWrapper(client, webSettings));
  }

  @Override public void setWebChromeClient(WebChromeClient client) {
    super.setWebChromeClient(new WebChromeClientWrapper(client));
  }

  @Override public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        if (this.getScrollY() <= 0) {
            this.scrollTo(0, 1);
        }
        break;
      case MotionEvent.ACTION_UP:
        //                if(this.getScrollY() == 0)
        //                this.scrollTo(0,-1);
        break;
      default:
        break;
    }
    return super.onTouchEvent(ev);
  }

  final class WebViewClientWrapper extends WebViewClient {
    final WebViewClient webViewClient;
    final WebSettings webSettings;

    private WebViewClientWrapper(@NonNull WebViewClient webViewClient,
        @NonNull WebSettings webSettings) {
      this.webViewClient = webViewClient;
      this.webSettings = webSettings;
    }

    @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
      return webViewClient.shouldOverrideUrlLoading(view, url);
    }

    @Override public void onPageStarted(WebView view, String url, Bitmap favicon) {
      webViewClient.onPageStarted(view, url, favicon);
    }

    @Override public void onPageFinished(WebView view, String url) {
      webViewClient.onPageFinished(view, url);
      if (!webSettings.getLoadsImagesAutomatically()) {
        webSettings.setLoadsImagesAutomatically(true);
      }
    }

    @Override public void onLoadResource(WebView view, String url) {
      webViewClient.onLoadResource(view, url);
    }

    @TargetApi(Build.VERSION_CODES.M) @Override
    public void onPageCommitVisible(WebView view, String url) {
      webViewClient.onPageCommitVisible(view, url);
    }

    @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
      return webViewClient.shouldInterceptRequest(view, url);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
      return webViewClient.shouldInterceptRequest(view, request);
    }

    @Override public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) {
      webViewClient.onTooManyRedirects(view, cancelMsg, continueMsg);
    }

    @Override public void onReceivedError(WebView view, int errorCode, String description,
        String failingUrl) {
      //loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
      String data = "  ";
      loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
      webViewClient.onReceivedError(view, errorCode, description, failingUrl);
    }

    @TargetApi(Build.VERSION_CODES.M) @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
      webViewClient.onReceivedError(view, request, error);
    }

    @TargetApi(Build.VERSION_CODES.M) @Override
    public void onReceivedHttpError(WebView view, WebResourceRequest request,
        WebResourceResponse errorResponse) {
      webViewClient.onReceivedHttpError(view, request, errorResponse);
    }

    @Override public void onFormResubmission(WebView view, Message dontResend, Message resend) {
      webViewClient.onFormResubmission(view, dontResend, resend);
    }

    @Override public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) {
      webViewClient.doUpdateVisitedHistory(view, url, isReload);
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
      super.onReceivedSslError(view, handler, error);
      webViewClient.onReceivedSslError(view, handler, error);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
      webViewClient.onReceivedClientCertRequest(view, request);
    }

    @Override
    public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
        String realm) {
      webViewClient.onReceivedHttpAuthRequest(view, handler, host, realm);
    }

    @Override public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
      return webViewClient.shouldOverrideKeyEvent(view, event);
    }

    @Override public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
      webViewClient.onUnhandledKeyEvent(view, event);
    }

    @Override public void onScaleChanged(WebView view, float oldScale, float newScale) {
      webViewClient.onScaleChanged(view, oldScale, newScale);
    }

    @Override
    public void onReceivedLoginRequest(WebView view, String realm, String account, String args) {
      webViewClient.onReceivedLoginRequest(view, realm, account, args);
    }
  }

  final class WebChromeClientWrapper extends WebChromeClient {
    final WebChromeClient webChromeClient;

    private WebChromeClientWrapper(@NonNull WebChromeClient webChromeClient) {
      this.webChromeClient = webChromeClient;
    }

    @Override public void onProgressChanged(WebView view, int newProgress) {
      webChromeClient.onProgressChanged(view, newProgress);
    }

    @Override public void onReceivedTitle(WebView view, String title) {
      webChromeClient.onReceivedTitle(view, title);
    }

    @Override public void onReceivedIcon(WebView view, Bitmap icon) {
      webChromeClient.onReceivedIcon(view, icon);
    }

    @Override public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed) {
      webChromeClient.onReceivedTouchIconUrl(view, url, precomposed);
    }

    @Override public void onShowCustomView(View view, CustomViewCallback callback) {
      webChromeClient.onShowCustomView(view, callback);
    }

    @Override
    public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
      webChromeClient.onShowCustomView(view, requestedOrientation, callback);
    }

    @Override public void onHideCustomView() {
      webChromeClient.onHideCustomView();
    }

    @Override public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture,
        Message resultMsg) {
      return webChromeClient.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
    }

    @Override public void onRequestFocus(WebView view) {
      webChromeClient.onRequestFocus(view);
    }

    @Override public void onCloseWindow(WebView window) {
      webChromeClient.onCloseWindow(window);
    }

    @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
      return webChromeClient.onJsAlert(view, url, message, result);
    }

    @Override
    public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
      return webChromeClient.onJsConfirm(view, url, message, result);
    }

    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
        JsPromptResult result) {
      return webChromeClient.onJsPrompt(view, url, message, defaultValue, result);
    }

    @Override
    public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
      return webChromeClient.onJsBeforeUnload(view, url, message, result);
    }

    @Override public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota,
        long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) {
      webChromeClient.onExceededDatabaseQuota(url, databaseIdentifier, quota, estimatedDatabaseSize,
          totalQuota, quotaUpdater);
    }

    @Override public void onReachedMaxAppCacheSize(long requiredStorage, long quota,
        WebStorage.QuotaUpdater quotaUpdater) {
      webChromeClient.onReachedMaxAppCacheSize(requiredStorage, quota, quotaUpdater);
    }

    @Override public void onGeolocationPermissionsShowPrompt(String origin,
        GeolocationPermissions.Callback callback) {
      webChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
    }

    @Override public void onGeolocationPermissionsHidePrompt() {
      webChromeClient.onGeolocationPermissionsHidePrompt();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public void onPermissionRequest(PermissionRequest request) {
      webChromeClient.onPermissionRequest(request);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public void onPermissionRequestCanceled(PermissionRequest request) {
      webChromeClient.onPermissionRequestCanceled(request);
    }

    @Override public boolean onJsTimeout() {
      return webChromeClient.onJsTimeout();
    }

    @Override public void onConsoleMessage(String message, int lineNumber, String sourceID) {
      webChromeClient.onConsoleMessage(message, lineNumber, sourceID);
    }

    @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
      return webChromeClient.onConsoleMessage(consoleMessage);
    }

    @Override public Bitmap getDefaultVideoPoster() {
      return webChromeClient.getDefaultVideoPoster();
    }

    @Override public View getVideoLoadingProgressView() {
      return webChromeClient.getVideoLoadingProgressView();
    }

    @Override public void getVisitedHistory(ValueCallback<String[]> callback) {
      webChromeClient.getVisitedHistory(callback);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
        FileChooserParams fileChooserParams) {
      return webChromeClient.onShowFileChooser(webView, filePathCallback, fileChooserParams);
    }
  }
}

 BridgeWebView

public class BridgeWebView extends WebView implements JsBridge, OnPageFinishedCallback {

  public  static final String TAG = "BridgeWebView";

  private BridgeDelegate bridgeDelegate;
  protected boolean neddRestoreResult = false;

  public BridgeWebView(Context context) {
    super(context);
    init();
  }

  public BridgeWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init();
  }

  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  public BridgeWebView(Context context, AttributeSet attrs, int defStyleAttr,
      boolean privateBrowsing) {
    super(context, attrs, defStyleAttr, privateBrowsing);
    init();
  }

  private void init() {
    if (isInEditMode()) {
      return;
    }

    bridgeDelegate = new BridgeDelegate(this);
    WebSettings settings = getSettings();
    settings.setSavePassword(false);

    //图片加载
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      settings.setLoadsImagesAutomatically(true);
    } else {
      settings.setLoadsImagesAutomatically(false);
      settings.setBlockNetworkImage(false);
    }
    if (Build.VERSION.SDK_INT >= 21) {
      settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }

    //js
    settings.setJavaScriptEnabled(true);
    settings.setJavaScriptCanOpenWindowsAutomatically(true);

    //缓存
    settings.setDomStorageEnabled(true);
    settings.setDatabaseEnabled(true);
    settings.setAppCacheEnabled(true);
    settings.setCacheMode(WebSettings.LOAD_DEFAULT);

    //文件访问
    settings.setAllowContentAccess(true);
    settings.setAllowFileAccess(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      settings.setAllowFileAccessFromFileURLs(true);
    }

    //显示
    settings.setUseWideViewPort(true);
    settings.setLoadWithOverviewMode(true);
    settings.setSupportZoom(false);
    settings.setDisplayZoomControls(false);

    settings.setGeolocationEnabled(true);
    settings.setSupportMultipleWindows(true);
    settings.setSaveFormData(true);

    removeJavascriptInterface("searchBoxJavaBridge_");
    //允许跨域
    SystemUtils.enablecrossdomain(this);
    setWebChromeClient(new WebChromeClient());
    setWebViewClient(new WebViewClient());
  }


  @Override public void setWebChromeClient(WebChromeClient client) {
    super.setWebChromeClient(new BridgeWebChromeClient(bridgeDelegate, client));
  }

  @Override public void setWebViewClient(WebViewClient client) {
    super.setWebViewClient(new BridgeWebViewClient(this, client));
  }

  @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
    bridgeDelegate.onActivityResult(requestCode, resultCode, data);
  }

  @Override public void onRequestPermissionsResult(int requestCode, String[] permissions,
      int[] grantResults) {
    bridgeDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
  }

  public void onPermissionsGranted(int requestCode, List<String> perms) {
    bridgeDelegate.onPermissionsGranted(requestCode, perms);
  }

  public void onPermissionsDenied(int requestCode, List<String> perms) {
    bridgeDelegate.onPermissionsDenied(requestCode, perms);
  }

  @Override public void handleMessageFromJs(String message) {
    bridgeDelegate.handleMessageFromJs(message);
  }

  @Override public void registNativeModule(NativeModule nativeModule) {
    bridgeDelegate.registNativeModule(nativeModule);
  }

  @Override public <T extends JsModule> T getJsModule(Class<T> jsMTClass) {
    return bridgeDelegate.getJsModule(jsMTClass);
  }

  @Override public void invokeJsModule(String moduleName, String methodName, Object... args) {
    bridgeDelegate.invokeJsModule(moduleName, methodName, args);
  }

  @Override public void invokeJsCallback(String callbackId, JSONArray jsonArray) {
    bridgeDelegate.invokeJsCallback(callbackId, jsonArray);
  }

  public void flusMessageQueue() {
    bridgeDelegate.flusMessageQueue();
  }

  @Override public void enableDebug(boolean debug) {
    bridgeDelegate.enableDebug(debug);
  }

  @Override public void enableQuickInject(boolean quickInject) {
    bridgeDelegate.enableQuickInject(quickInject);
  }

  @Override public void tryInjectJsBridge(boolean reset, boolean forceInject) {
    bridgeDelegate.tryInjectJsBridge(reset, forceInject);
  }

  @Override protected void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(state);
    neddRestoreResult = true;
  }

  @Override public void onPageFinished(WebView view, String url) {
    bridgeDelegate.onPageFinished(view, url);
  }
}

 

 JSBridge

public interface JsBridge {

  String JS_BRIDGE_NAME = "NativeBridge";

  String BRIDGE_JS = "Bridge.js";

  String BRIDGE_SCHEME = "jsbridge://";

  String QUEUE_HAS_MESSAGE = BRIDGE_SCHEME + "has_message/";

  String RETURN_DATA = BRIDGE_SCHEME + "return_data/";

  String JS_HANDLE_MESSAGE_FROM_JAVA =
      "javascript:window." + JS_BRIDGE_NAME + ".handleMessageFromNative('%s');";

  String JS_FETCH_QUEUE = "javascript:window." + JS_BRIDGE_NAME + ".fetchQueue();";

  void enableDebug(boolean debug);

  /**
   * 是否启用快速注入。 如果注入的接口对象可能被h5覆盖可采用慢注入
   * @param quickInject  默认true, 如果 false,只会在pageFinish后注入
   */
  void enableQuickInject(boolean quickInject);

  /**
   * 尝试注入bridge。 为保证注入速度和成功率,会在多个时间尝试注入
   * @param reset  重置至未注入状态
   * @param force  不管是否已注入,强制再次注入
   */
  void tryInjectJsBridge(boolean reset, boolean force);

  void handleMessageFromJs(String message);

  void invokeJsModule(String moduleName, String methodName, Object[] args);

  void invokeJsCallback(String callbackId, JSONArray jsonArray);

  void registNativeModule(NativeModule bridgeModule);

  <T extends JsModule> T getJsModule(Class<T> jsMTClass);

  void flusMessageQueue();

  void onActivityResult(int requestCode, int resultCode, Intent data);

  void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);

  void onPermissionsGranted(int requestCode, List<String> perms);

  void onPermissionsDenied(int requestCode, List<String> perms);
}

 OnPageFinishedCallback

public interface OnPageFinishedCallback {
  void onPageFinished(WebView view, String url);
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值