IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> [jni] [android] 用C++开发安卓程序 -> 正文阅读

[移动开发][jni] [android] 用C++开发安卓程序

原理

原理其实很简单
首先用FindClass()查找java类,然后用GetMethodID()得到构造函数
构造函数的函数名是“< init >”,返回类型为"V"(void)
最后直接用NewObject()创建一个按钮
回调部分受到了别人文章和快写代码的启发,把回调类的地址传递到java中,java类接收到事件后用地址作为参数调用本地方法,本地方法把地址转换为c++回调类,调用方法

代码

MainActivity.java

package com.Diamond.ndk;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.content.Context;
import android.widget.Button;

public class MainActivity extends Activity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Context context = MainActivity.this;
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(1);
        setContentView(mainLayout);
        
        onCreate(context,mainLayout);
    }

    @Override
    protected void onDestroy() {
        onActivityDestroy();
        super.onDestroy();
    }
	
    public native void onActivityDestroy();
    public native void onCreate(Context context,LinearLayout mainLayout);
    static {
        System.loadLibrary("jni");
    }
} 

MyOnClickListener.java

package com.Diamond.ndk;
import android.view.View;
import android.util.Log;

public class MyOnClickListener implements View.OnClickListener {
    public int address;
    
    public MyOnClickListener(int ar) {
        address = ar;
    }
    
    @Override
    public void onClick(View p1) {
        callOnClick(address);
        Log.d("address","" + address);
    }
    
    public native void callOnClick(long address);
    static {
        System.loadLibrary("jni");
    }
}

main.cpp

#include <sstream>
#include <jni.h>
#include <android/log.h>
	using namespace std;

extern "C"
{
	class OnClickListener
	{
	  public:
		virtual void onClick() = 0;
	};

	JNIEnv *Env = NULL;
	jobject button = NULL;
	const string linearlayout_package = "android/widget/LinearLayout";
	const string context_package = "android/content/Context";
	const string button_package = "android/widget/Button";
	const string view_package = "android/view/View";
	const string charsequence_package = "java/lang/CharSequence";
	const string myonclicklistener_package = "com/Diamond/ndk/MyOnClickListener";
	const string onclicklistener_package = "android/view/View$OnClickListener";

	jclass LinearLayout = NULL;
	jclass Context = NULL;
	jclass Button = NULL;
	jclass View = NULL;
	jclass MyOnClickListener = NULL;

	jmethodID init_button = NULL;
	jmethodID init_myonclicklistener = NULL;
	jmethodID addView_linearlayout = NULL;
	jmethodID setText_button = NULL;

	jclass getClass(string package);
	void setText(jobject button, string text);

	class MyListener : public OnClickListener
	{
	  public:
		virtual void onClick()
		{
            //用了会崩溃,不知道为什么
			//setText(button, "be clicked");
			__android_log_print(ANDROID_LOG_INFO, "test", "test");
		}
	};

	MyListener *listener = NULL;

	JNIEXPORT void JNICALL Java_com_Diamond_ndk_MainActivity_onCreate(JNIEnv * env, jobject thiz,
																	  jobject context,
																	  jobject mainLayout)
	{
		Env = env;

		LinearLayout = getClass(linearlayout_package);
		Context = getClass(context_package);
		Button = getClass(button_package);
		View = getClass(view_package);
		MyOnClickListener = getClass(myonclicklistener_package);

		setText_button =
			Env->GetMethodID(Button, "setText", ("(L" + charsequence_package + ";)V").data());

		init_button = env->GetMethodID(Button, "<init>", ("(L" + context_package + ";)V").data());
		button = env->NewObject(Button, init_button, context);
		setText(button, "JNI Button");

		listener = new MyListener();
		jmethodID setOnClickListener_button = env->GetMethodID(Button, "setOnClickListener",
															   ("(L" + onclicklistener_package +
																";)V").data());
		init_myonclicklistener = env->GetMethodID(MyOnClickListener, "<init>", "(I)V");
		jobject myonclicklistener =
			env->NewObject(MyOnClickListener, init_myonclicklistener, jint(listener));
		env->CallVoidMethod(button, setOnClickListener_button, myonclicklistener);

		addView_linearlayout =
			env->GetMethodID(LinearLayout, "addView", ("(L" + view_package + ";)V").data());
		env->CallVoidMethod(mainLayout, addView_linearlayout, button);
	}

	JNIEXPORT void JNICALL Java_com_Diamond_ndk_MainActivity_onActivityDestroy(JNIEnv * env,
																			   jobject thiz)
	{
		delete listener;
	}

	JNIEXPORT void JNICALL Java_com_Diamond_ndk_MyOnClickListener_callOnClick(JNIEnv * env,
																			  jobject thiz,
																			  jint address)
	{
		OnClickListener *listener = (OnClickListener *) address;
		listener->onClick();
	}

	jclass getClass(string package)
	{
		return Env->FindClass(package.data());
	}

	void setText(jobject button, string text)
	{
		Env->CallVoidMethod(button, setText_button, Env->NewStringUTF(text.data()));
	}
}

效果图

在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-18 17:54:07  更:2022-04-18 17:54:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 20:35:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码