Android browser kitkat中关于jni的调用

来源:互联网 发布:手机上怎么查淘宝评价 编辑:程序博客网 时间:2024/05/23 14:25

#############################################

本文为极度寒冰原创,转载请注明出处
#############################################

曾经有一位心目中的大牛说过一句话,chromium中有很多很多的新技术。这些让你非常的着迷,而现在android kitkat的面试,会将这些新技术让更多的人去了解。

今天,就将去研究一下kitkat的browser关于jni的调用。
首先在4.4之前的版本上面,jni的调用一般是这样实现的。

在java端:
声明一个native函数
private native void nativeLoadUrl(String url, Map<String, String> headers);
使用的时候:
    public void loadUrl(String url, Map<String, String> extraHeaders) {        mLoadInitFromJava = true;        if (URLUtil.isJavaScriptUrl(url)) {            // strip off the scheme and evaluate the string            stringByEvaluatingJavaScriptFromString(                    url.substring("javascript:".length()));        } else {            nativeLoadUrl(url, extraHeaders);        }        mLoadInitFromJava = false;    }

而在cpp端,会有一个native method数组,比如
static JNINativeMethod gBrowserFrameNativeMethods[] = {    /* name, signature, funcPtr */    { "nativeCallPolicyFunction", "(II)V",        (void*) CallPolicyFunction },    { "nativeCreateFrame", "(Landroid/webkit/WebViewCore;Landroid/content/res/AssetManager;Landroid/webkit/WebBackForwardList;)V",        (void*) CreateFrame },    { "nativeDestroyFrame", "()V",        (void*) DestroyFrame },    { "nativeStopLoading", "()V",        (void*) StopLoading },    { "nativeLoadUrl", "(Ljava/lang/String;Ljava/util/Map;)V",        (void*) LoadUrl },

然后就可以找到这个函数的具体实现:
static void LoadUrl(JNIEnv *env, jobject obj, jstring url, jobject headers)

但是现在的kitkat中,因为是使用的chromium的引擎。所以流程发生了一些改变:
java端:
    public void loadUrl(LoadUrlParams params) {        if (mNativeContentViewCore == 0) return;        nativeLoadUrl(mNativeContentViewCore,                params.mUrl,                params.mLoadUrlType,                params.mTransitionType,                params.mUaOverrideOption,                params.getExtraHeadersString(),                params.mPostData,                params.mBaseUrlForDataUrl,                params.mVirtualUrlForDataUrl,                params.mCanLoadLocalResources);    }
在cpp端的h文件中,会直接继承并声明
class ContentViewCoreImpl : public ContentViewCore,                            public NotificationObserver {

然后函数会用Jni的参数来进行声明:
  void LoadUrl(      JNIEnv* env, jobject obj,      jstring url,      jint load_url_type,      jint transition_type,      jint ua_override_option,      jstring extra_headers,      jbyteArray post_data,      jstring base_url_for_data_url,      jstring virtual_url_for_data_url,      jboolean can_load_local_resources);
这样就省却了声明native method的操作。
再往下面就是函数的实现了:
void ContentViewCoreImpl::LoadUrl(    JNIEnv* env, jobject obj,    jstring url,    jint load_url_type,    jint transition_type,    jint ua_override_option,    jstring extra_headers,    jbyteArray post_data,    jstring base_url_for_data_url,    jstring virtual_url_for_data_url,    jboolean can_load_local_resources) {  DCHECK(url);  NavigationController::LoadURLParams params(      GURL(ConvertJavaStringToUTF8(env, url)));  params.load_type = static_cast<NavigationController::LoadURLType>(      load_url_type);  params.transition_type = PageTransitionFromInt(transition_type);  params.override_user_agent =      static_cast<NavigationController::UserAgentOverrideOption>(          ua_override_option);  if (extra_headers)    params.extra_headers = ConvertJavaStringToUTF8(env, extra_headers);  if (post_data) {    std::vector<uint8> http_body_vector;    base::android::JavaByteArrayToByteVector(env, post_data, &http_body_vector);    params.browser_initiated_post_data =        base::RefCountedBytes::TakeVector(&http_body_vector);  }  if (base_url_for_data_url) {    params.base_url_for_data_url =        GURL(ConvertJavaStringToUTF8(env, base_url_for_data_url));  }  if (virtual_url_for_data_url) {    params.virtual_url_for_data_url =        GURL(ConvertJavaStringToUTF8(env, virtual_url_for_data_url));  }  params.can_load_local_resources = can_load_local_resources;  LoadUrl(params);}

这下应该就是一个完整的jni调用了 ~~~