Android WebView相关交互实现

一、支持网页视频播放

设置自定义WebChromeClient,覆写 onShowCustomView onHideCustomView,将WebChromeClient提供的 view 添加到布局中即可。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
webChromeClient = object : WebChromeClient() {
override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
mViewBinding.flVideoContainer.run {
visibility = View.VISIBLE
addView(view)
}
}
override fun onHideCustomView() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
mViewBinding.flVideoContainer.run {
visibility = View.GONE
removeAllViews()
}
}
}
webChromeClient = object : WebChromeClient() { override fun onShowCustomView(view: View?, callback: CustomViewCallback?) { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE mViewBinding.flVideoContainer.run { visibility = View.VISIBLE addView(view) } } override fun onHideCustomView() { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR mViewBinding.flVideoContainer.run { visibility = View.GONE removeAllViews() } } }
webChromeClient = object : WebChromeClient() {
    override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
        mViewBinding.flVideoContainer.run {
            visibility = View.VISIBLE
            addView(view)
        }
    }

    override fun onHideCustomView() {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR
        mViewBinding.flVideoContainer.run {
            visibility = View.GONE
            removeAllViews()
        }
    }
}
继续阅读“Android WebView相关交互实现”

Android:修改当前App某个窗口参数

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
try {
WindowManager manager = getWindowManager();
Field mGlobal_field = manager.getClass().getDeclaredField("mGlobal");
mGlobal_field.setAccessible(true);
Object managerGlobal = mGlobal_field.get(manager);
//noinspection ConstantConditions
Field mViews_field = managerGlobal.getClass().getDeclaredField("mViews");
mViews_field.setAccessible(true);
//noinspection unchecked
ArrayList<View> mViews = (ArrayList<View>) mViews_field.get(managerGlobal);
//noinspection ConstantConditions
View dialogDecorView = mViews.get(mViews.size() - 1);// TODO 这里需要做一下判断,是不是dialog的decorView
WindowManager.LayoutParams params = (WindowManager.LayoutParams) dialogDecorView.getLayoutParams();
params.gravity = Gravity.TOP;
dialogDecorView.setLayoutParams(params);
manager.removeView(dialogDecorView);
manager.addView(dialogDecorView, params);
} catch (Exception e) {
e.printStackTrace();
}
try { WindowManager manager = getWindowManager(); Field mGlobal_field = manager.getClass().getDeclaredField("mGlobal"); mGlobal_field.setAccessible(true); Object managerGlobal = mGlobal_field.get(manager); //noinspection ConstantConditions Field mViews_field = managerGlobal.getClass().getDeclaredField("mViews"); mViews_field.setAccessible(true); //noinspection unchecked ArrayList<View> mViews = (ArrayList<View>) mViews_field.get(managerGlobal); //noinspection ConstantConditions View dialogDecorView = mViews.get(mViews.size() - 1);// TODO 这里需要做一下判断,是不是dialog的decorView WindowManager.LayoutParams params = (WindowManager.LayoutParams) dialogDecorView.getLayoutParams(); params.gravity = Gravity.TOP; dialogDecorView.setLayoutParams(params); manager.removeView(dialogDecorView); manager.addView(dialogDecorView, params); } catch (Exception e) { e.printStackTrace(); }
            try {
                WindowManager manager = getWindowManager();
                Field mGlobal_field = manager.getClass().getDeclaredField("mGlobal");
                mGlobal_field.setAccessible(true);
                Object managerGlobal = mGlobal_field.get(manager);
                //noinspection ConstantConditions
                Field mViews_field = managerGlobal.getClass().getDeclaredField("mViews");
                mViews_field.setAccessible(true);
                //noinspection unchecked
                ArrayList<View> mViews = (ArrayList<View>) mViews_field.get(managerGlobal);
                //noinspection ConstantConditions
                View dialogDecorView = mViews.get(mViews.size() - 1);// TODO 这里需要做一下判断,是不是dialog的decorView
                WindowManager.LayoutParams params = (WindowManager.LayoutParams) dialogDecorView.getLayoutParams();
                params.gravity = Gravity.TOP;
                dialogDecorView.setLayoutParams(params);
                manager.removeView(dialogDecorView);
                manager.addView(dialogDecorView, params);
            } catch (Exception e) {
                e.printStackTrace();
            }

几个常用排序算法

插入排序

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
fun insertSort(arr: IntArray) {
for (i in 1 <em>until </em>arr.size) {
val temp = arr[i]
var preIndex = i - 1
while (preIndex >= 0 && arr[preIndex] > temp) {
arr[preIndex + 1] = arr[preIndex]
preIndex--
}
arr[preIndex + 1] = temp
}
}
fun insertSort(arr: IntArray) { for (i in 1 <em>until </em>arr.size) { val temp = arr[i] var preIndex = i - 1 while (preIndex >= 0 && arr[preIndex] > temp) { arr[preIndex + 1] = arr[preIndex] preIndex-- } arr[preIndex + 1] = temp } }
fun insertSort(arr: IntArray) {
    for (i in 1 <em>until </em>arr.size) {
        val temp = arr[i]
        var preIndex = i - 1
        while (preIndex >= 0 && arr[preIndex] > temp) {
            arr[preIndex + 1] = arr[preIndex]
            preIndex--
        }
        arr[preIndex + 1] = temp
    }
}
继续阅读“几个常用排序算法”

RxJava简析

注:本文章代码基于 RxJava:3.0.0-RC4

一、概述

官方描述: RxJava是反应式编程扩展的JVM实现:该库用于通过使用可观察的序列来组成异步和基于事件的程序。

即:RxJava 是一个用反应式编程特性来扩展观察者模式的事件处理库。

ReactiveX官网的流概念图 通过去抖实现可控的事件触发
继续阅读“RxJava简析”

Android: SingleInstance 填坑 —— 返回上一级Activity

因为一个多任务的需求,所以想到了使用 SingleInstance 方式启动多任务容器 Activity,保证一定情况内 Activity 不被销毁,可以随时切换回来操作。

基于面向百度编程可知 SingleInstance 会另开一个返回栈(Task)来启动该 Activity,但首先有两个问题需要解决:

1. 如何从SingleInstance 返回到上一个 Activity
2. ActivityResult的实现

继续阅读“Android: SingleInstance 填坑 —— 返回上一级Activity”

Android: 使用XStream解析.Net后台序列化的XML

因业务需要在Android端解析.net后台接口传递的XML,由于Android精简了jdk,无法使用原生XMLDecoder,因此选择了XStream实现。

C#后台使用原生XmlSerializer序列化

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public static string Serialize(object data)
{
string result = string.Empty;
try
{
using (MemoryStream ms = new MemoryStream())
{
XmlSerializer xml = new XmlSerializer(data.GetType());
xml.Serialize(ms, data);
byte[] arr = ms.ToArray();
result = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
}
}
catch (Exception ex)
{
throw;
}
return result;
}
public static string Serialize(object data) { string result = string.Empty; try { using (MemoryStream ms = new MemoryStream()) { XmlSerializer xml = new XmlSerializer(data.GetType()); xml.Serialize(ms, data); byte[] arr = ms.ToArray(); result = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); } } catch (Exception ex) { throw; } return result; }
    public static string Serialize(object data)
    {
        string result = string.Empty;
        try
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer xml = new XmlSerializer(data.GetType());
                xml.Serialize(ms, data);
                byte[] arr = ms.ToArray();
                result = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
            }
        }
        catch (Exception ex)
        {
            throw;
        }
        return result;
    }


移动端使用XStream对接口返回的XML进行解析,注意的是如果序列化的实体类中的字段包含其它实体类,解析时需要为其设置对应类的别名,下面通过反射获取这些类

继续阅读“Android: 使用XStream解析.Net后台序列化的XML”