1 布局
<ScrollView
android:id="@+id/scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:progressDrawable="@drawable/progress_webview" />
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
<com.zjxnkj.countrysidecommunity.view.ScrollWebView
android:id="@+id/news_webView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</ScrollView>
2 设置webView属性
private void setWebSetting() {
WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(false);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//开启DOM缓存,关闭的话H5自身的一些操作是无效的
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");
webView.setWebChromeClient(new MyWebChromeClient());
webView.setWebViewClient(new MyWebViewClient(webView));
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context
.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info.isAvailable()) {
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
} else {
settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//不使用网络,只加载缓存
}
String ua = webView.getSettings().getUserAgentString();
webView.getSettings().setUserAgentString(ua + "/userDefinition");
loadUrl(URL, webView);
}
public class JavascriptInterface {
private Context context;
public JavascriptInterface(Context context) {
this.context = context;
}
@android.webkit.JavascriptInterface
public void readImageUrl(String img) { //把所有图片的url保存在ArrayList<String>中
images.add(img);
}
@android.webkit.JavascriptInterface
public void openImage(String clickimg) {
ArrayList<String> list = addImages();
String[] imageUrls = list.toArray(new String[list.size()]);
/*Intent intent = new Intent(context, ShowImageActivity.class);
intent.putExtra("imageUrls", imageUrls);
intent.putExtra("curImageUrl", clickimg);
startActivity(intent);*/
}
}
/**
* 自定义弹出框
*/
class MyWebChromeClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle("消息提示")
.setMessage(message)
.setPositiveButton("确定", null);
// 不需要绑定按键事件
// 屏蔽keycode等于84之类的按键
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
return true;
}
});
// 禁止响应按back键的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
result.confirm();// 因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
return true;
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
currentProgress = mProgressBar.getProgress();
if (newProgress >= 100 && !isAnimStart) {
// 防止调用多次动画
isAnimStart = true;
mProgressBar.setProgress(newProgress);
// 开启属性动画让进度条平滑消失
startDismissAnimation(mProgressBar.getProgress());
} else {
// 开启属性动画让进度条平滑递增
startProgressAnimation(newProgress);
}
}
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
builder.setTitle("消息提示")
.setMessage(message)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNeutralButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.cancel();
}
});
// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
return true;
}
});
// 禁止响应按back键的事件
// builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
// return super.onJsConfirm(view, url, message, result);
}
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
return super.onJsBeforeUnload(view, url, message, result);
}
}
/**
* 自定义回调
*/
class MyWebViewClient extends BridgeWebViewClient {
public MyWebViewClient(BridgeWebView webView) {
super(webView);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//DialogShow.showRoundProcessDialog();
}
@Override
public void onPageFinished(WebView view, String url) {
DialogShow.closeDialog();
addImageClickListner();
llContent.setVisibility(View.VISIBLE);
if (ScrollY != 0) {
webView.scrollTo(ScrollX, ScrollY);
}
//这个是一定要加上那个的,配合scrollView和WebView的height=wrap_content属性使用
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
//重新测量
webView.measure(w, h);
super.onPageFinished(view, url);
}
}
3 加载
/**
* 加载URL
*
* @param url
*/
public void loadUrl(String url, BridgeWebView webView) {
CookieManager cookieManager = CookieManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cookieManager.setAcceptThirdPartyCookies(webView, true);
}
setCookie(url);
Map extraHeaders = new HashMap();
extraHeaders.put("Referer", "http://"+ UrlConstants.IP_WITH_PORT);
Map<String,String> map=new HashMap<>();
map.put("tokenId", App.tokenId);
webView.loadUrl(url,map);
}
4
/**
* 设置Cookie
* @param url
*/
public void setCookie(String url) {
cookieStore = new PersistentCookieStore(getApplicationContext());
List<Cookie> cookieList = cookieStore.getCookies();
if (isUrl(url)) {
CookieManager cookieManager = CookieManager.getInstance();
// 同步所有的Cookie到webview中
for (Cookie cookie : cookieList) {
String cookieString = cookie.name() + "=" + cookie.value() + "; domain=" + cookie
.domain() + "; path=" + cookie.path();
cookieManager.setCookie(url, cookieString);
CookieSyncManager.getInstance().sync();
}
}
}
5
public class PersistentCookieStore {
private static final String LOG_TAG = "PersistentCookieStore";
private static final String COOKIE_PREFS = "Cookies_Prefs";
private final Map<String, ConcurrentHashMap<String, Cookie>> cookies;
private final SharedPreferences cookiePrefs;
public PersistentCookieStore(Context context) {
cookiePrefs = context.getSharedPreferences(COOKIE_PREFS, 0);
cookies = new HashMap<>();
//将持久化的cookies缓存到内存中 即map cookies
Map<String, ?> prefsMap = cookiePrefs.getAll();
for (Map.Entry<String, ?> entry : prefsMap.entrySet()) {
String[] cookieNames = TextUtils.split((String) entry.getValue(), ",");
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(name, null);
if (encodedCookie != null) {
Cookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
if (!cookies.containsKey(entry.getKey())) {
cookies.put(entry.getKey(), new ConcurrentHashMap<String, Cookie>());
}
cookies.get(entry.getKey()).put(name, decodedCookie);
}
}
}
}
}
protected String getCookieToken(Cookie cookie) {
return cookie.name() + "@" + cookie.domain();
}
public void add(HttpUrl url, Cookie cookie) {
String name = getCookieToken(cookie);
//将cookies缓存到内存中 如果缓存过期 就重置此cookie
if (!cookie.persistent()) {
if (!cookies.containsKey(url.host())) {
cookies.put(url.host(), new ConcurrentHashMap<String, Cookie>());
}
cookies.get(url.host()).put(name, cookie);
} else {
if (cookies.containsKey(url.host())) {
cookies.get(url.host()).remove(name);
}
}
//讲cookies持久化到本地
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.putString(name, encodeCookie(new SerializableOkHttpCookies(cookie)));
prefsWriter.apply();
}
public List<Cookie> get(HttpUrl url) {
ArrayList<Cookie> ret = new ArrayList<>();
if (cookies.containsKey(url.host()))
ret.addAll(cookies.get(url.host()).values());
return ret;
}
public boolean removeAll() {
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
prefsWriter.clear();
prefsWriter.apply();
cookies.clear();
return true;
}
public boolean remove(HttpUrl url, Cookie cookie) {
String name = getCookieToken(cookie);
if (cookies.containsKey(url.host()) && cookies.get(url.host()).containsKey(name)) {
cookies.get(url.host()).remove(name);
SharedPreferences.Editor prefsWriter = cookiePrefs.edit();
if (cookiePrefs.contains(name)) {
prefsWriter.remove(name);
}
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.apply();
return true;
} else {
return false;
}
}
public List<Cookie> getCookies() {
ArrayList<Cookie> ret = new ArrayList<>();
for (String key : cookies.keySet())
ret.addAll(cookies.get(key).values());
return ret;
}
/**
* cookies 序列化成 string
*
* @param cookie 要序列化的cookie
* @return 序列化之后的string
*/
protected String encodeCookie(SerializableOkHttpCookies cookie) {
if (cookie == null)
return null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (IOException e) {
Log.d(LOG_TAG, "IOException in encodeCookie", e);
return null;
}
return byteArrayToHexString(os.toByteArray());
}
/**
* 将字符串反序列化成cookies
*
* @param cookieString cookies string
* @return cookie object
*/
protected Cookie decodeCookie(String cookieString) {
byte[] bytes = hexStringToByteArray(cookieString);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
Cookie cookie = null;
try {
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
cookie = ((SerializableOkHttpCookies) objectInputStream.readObject()).getCookies();
} catch (IOException e) {
Log.d(LOG_TAG, "IOException in decodeCookie", e);
} catch (ClassNotFoundException e) {
Log.d(LOG_TAG, "ClassNotFoundException in decodeCookie", e);
}
return cookie;
}
/**
* 二进制数组转十六进制字符串
*
* @param bytes byte array to be converted
* @return string containing hex values
*/
protected String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 2);
for (byte element : bytes) {
int v = element & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase(Locale.US);
}
/**
* 十六进制字符串转二进制数组
*
* @param hexString string of hex-encoded values
* @return decoded byte array
*/
protected byte[] hexStringToByteArray(String hexString) {
int len = hexString.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
}
return data;
}
}