cocos2dx-3.2调用java(jni)来内嵌网页

本文参照了Vincent Chou的个人博客文章:cocos2d-xiOS/Android双平台上嵌入WebView 和 Cocos2d-x中通过JNI进行C++调用Java代码


1.基本说明 

要通过jnicocos2d-xc++代码调用java函数,要使用到cocos2d-x中有一个JniHelper类。

头文件:#include "platform/android/jni/JniHelper.h"

       需要使用的接口如下:

const char *className, const char *methodName, const char *paramCode);
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
每个参数的意义和使用方法:
//函数信息结构体
    JniMethodInfo minfo;
    bool isHave = JniHelper::getStaticMethodInfo(minfo,/*JniMethodInfo的引用*/
                                                 "com/omega/MyApp",/*类的路径*/
                                                 "getJavaActivity",/*函数名*/
                                                 "()Ljava/lang/Object;");/*函数类型简写*/
    jobject activityObj;
    if (isHave)
    {
        //CallStaticObjectMethod调用java函数,并把返回值赋值给activityObj
        activityObj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
    }

这里重点要说明一下("com/omega/MyApp",/*类的路径*/),这个类的路径,我弄了很久才搞明白,它其实是你在创建android时使用的包名,比如com.xxx.xxx,如果你不知道或者忘记了是什么可以打开 proj.android目录下的AndroidManifest.xml文件查看, package="com.cocos2dx.example" 中的 "com.cocos2dx.example" 就是你的包名。下面继续


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.cocos2dx.example"
      android:versionCode="1"
      android:versionName="1.0">

  .....



源文件是放在:youProject\proj.android\src\org\cocos2dx\cpp\AppActivity.java下,比如我的JAVA函数是写在AppActivity.java文件当,那么最终这里类的路径就是: "proj.android\src\org\cocos2dx\cpp\AppActivity.java" .

AppActivity.java 代码如下:

/****************************************************************************
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011      Zynga Inc.
Copyright (c) 2013-2014 Chukong Technologies Inc.
 
http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;

import org.cocos2dx.hellocpp.R;

import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class AppActivity extends Cocos2dxActivity{
	
    static AppActivity test  = null;
	WebView m_webView;
    ImageView m_imageView;
    FrameLayout m_webLayout;
    LinearLayout m_topLayout;
    Button m_backButton;

	
    protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
        test=this;
        Log.v("cccccc","onCreate");
        //初始化一个空布局
        m_webLayout = new FrameLayout(this);
        FrameLayout.LayoutParams lytp = new FrameLayout.LayoutParams(800,640);
        lytp .gravity = Gravity.CENTER;
        addContentView(m_webLayout, lytp);
	}
    
  //返回实例
    public static AppActivity getInstance() {
        Log.v("aaaaa","getInstance");
    	return test;
    }
    public void openWebview() {
    	this.runOnUiThread(new Runnable() {//在主线程里添加别的控件
            public void run() {   
                //初始化webView
                m_webView = new WebView(test);
                //设置webView能够执行javascript脚本
                m_webView.getSettings().setJavaScriptEnabled(true);            
                //设置可以支持缩放
                m_webView.getSettings().setSupportZoom(true);//设置出现缩放工具
                m_webView.getSettings().setBuiltInZoomControls(true);
                //载入URL
                m_webView.loadUrl("http://www.baidu.com");
                //使页面获得焦点
                m_webView.requestFocus();
                //如果页面中链接,如果希望点击链接继续在当前browser中响应
                m_webView.setWebViewClient(new WebViewClient(){       
                    public boolean shouldOverrideUrlLoading(WebView view, String url) {   
                        if(url.indexOf("tel:")<0){
                            view.loadUrl(url); 
                        }
                        return true;       
                    }    
                });
                
                //背景图
                m_imageView = new ImageView(test);
                m_imageView.setImageResource(R.drawable.bkgnd);
                m_imageView.setScaleType(ImageView.ScaleType.FIT_XY);
                //初始化线性布局 里面加按钮和webView
                m_topLayout = new LinearLayout(test);      
                m_topLayout.setOrientation(LinearLayout.VERTICAL);
                //初始化返回按钮
                m_backButton = new Button(test);
                Log.v("zzzz2", "openWebView");
             //   m_backButton.setBackgroundResource(R.drawable.btn);
                Log.v("zzzz3", "openWebView");
                LinearLayout.LayoutParams lypt=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                lypt.gravity=Gravity.RIGHT;
                m_backButton.setLayoutParams(lypt);            
                m_backButton.setOnClickListener(new OnClickListener() {                    
                    public void onClick(View v) {
                        removeWebView();
                    }
                });
                //把image加到主布局里
                m_webLayout.addView(m_imageView);
                //把webView加入到线性布局
                m_topLayout.addView(m_backButton);
                m_topLayout.addView(m_webView);                
                //再把线性布局加入到主布局
                m_webLayout.addView(m_topLayout);
            }
        });
    }
    //移除webView
    public void removeWebView() {              
    	m_webLayout.removeView(m_imageView);
        m_imageView.destroyDrawingCache();
        
        m_webLayout.removeView(m_topLayout);
        m_topLayout.destroyDrawingCache();
                
        m_topLayout.removeView(m_webView);
        m_webView.destroy();
                
        m_topLayout.removeView(m_backButton);
        m_backButton.destroyDrawingCache();
    }
    
    //重写return键
    public boolean onKeyDown(int keyCoder,KeyEvent event)
    {
    	//如果网页能回退则后退,如果不能后退移除WebView
    	if(m_webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){
            m_webView.goBack();
        }else{
            removeWebView();
        }
        return false;      
    }

    public Cocos2dxGLSurfaceView onCreateView() {
    	Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
    	// Test should create stencil buffer
    	glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
    	
    	return glSurfaceView;
    }

    static {
    	  
        System.loadLibrary("cocos2dcpp");
    }     
}


HelloWord.cpp 代码如下:

#include "HelloWorldScene.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#endif

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    /
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));

    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

    /
    // 3. add your codes below...

    // add a label shows "Hello World"
    // create and initialize a label
    
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    
    // position the label on the center of the screen
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));

    // add the label as a child to this layer
    this->addChild(label, 1);

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(sprite, 0);
    
    return true;
}


void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
	JniMethodInfo minfo;
	//getStaticMethodInfo,判断Java静态函数是否存在,并且把信息保存到minfo里
	//参数1:JniMethodInfo
	//参数2:Java类包名+类名
	//参数3:Java函数名称
	//参数4:函数参数类型和返回值类型
	bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","getInstance","()Lorg/cocos2dx/cpp/AppActivity;");
	jobject jobj;//存对象
//	log("aaa=%s,bbb=%s",minfo.classID,minfo.methodID);
	if (isHave) {
		//这里的调用getInstance,返回Test类的对象。
		jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
		if(jobj!=NULL){
			isHave = JniHelper::getMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","openWebview","()V");
			if (isHave) {				
				//调用openWebview, 参数1:Test对象   参数2:方法ID
				minfo.env->CallVoidMethod(jobj, minfo.methodID);
			
			}
		}
	}
#else
    CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
#endif
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
//	MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
//    return;
//#endif
//
//    Director::getInstance()->end();
//
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
//    exit(0);
//#endif
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值