当前位置: 首页 > news >正文

使用Android Studio运行NDK程序

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

首先配置NDK路径:点击File-->Project Structure,如下图所示:

设置路径之后点击OK配置完成,会在项目的local.properties文件中生成以下两行信息:

ndk.dir=E\:\\android-ndk-r13  ->NDK路径

sdk.dir=E\:\\AndroidSdk      ->SDK路径

在app\src\main\java\包目录下新建文件夹hardcontrol,并在里面建立HardControl.java文件,文件的内容如下:

package com.thisway.hardlibrary;

public class HardControl{

    public static native int ledCtrl(int which ,int status); //声明本地函数
    public static native int ledOpen();  //声明本地函数
    public static native void ledClose();  //声明本地函数

    static {
        try {
            System.loadLibrary("hardcontrol");  //加载动态库并捕获异常
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

MainActivity.java的代码如下:

package com.thisway.ndkdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Toast;
import com.thisway.hardcontrol.HardControl;

public class MainActivity extends AppCompatActivity {

    private Button mButton = null;
    private CheckBox led1 = null;
    private CheckBox led2 = null;
    private CheckBox led3 = null;
    private CheckBox led4 = null;

    private MyOnClickListener mListener = new MyOnClickListener();

    private boolean isPress = false;
    private boolean isChecked = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        HardControl.ledOpen(); //调用C实现的对应本地函数

        mButton = (Button)findViewById(R.id.button);

        led1 = (CheckBox)findViewById(R.id.led1);
        led2 = (CheckBox)findViewById(R.id.led2);
        led3 = (CheckBox)findViewById(R.id.led3);
        led4 = (CheckBox)findViewById(R.id.led4);

        mButton.setOnClickListener(mListener);

        led1.setOnClickListener(mListener);
        led2.setOnClickListener(mListener);
        led3.setOnClickListener(mListener);
        led4.setOnClickListener(mListener);
    }

    class MyOnClickListener implements View.OnClickListener{
        @Override
        public void onClick(View v) {

            int id = v.getId();

            switch (id){
                case R.id.button:
                    if (isPress){
                        mButton.setText("ALL OFF");
                        isPress = false;

                        led1.setChecked(false);
                        led2.setChecked(false);
                        led3.setChecked(false);
                        led4.setChecked(false);
                    }else {
                        mButton.setText("ALL ON");
                        isPress = true;
                        led1.setChecked(true);
                        led2.setChecked(true);
                        led3.setChecked(true);
                        led4.setChecked(true);
                    }
                    break;
                case R.id.led1:
                    isChecked = led1.isChecked();
                    if (isChecked){
                        Toast.makeText(getApplicationContext(),"led1 on",Toast.LENGTH_SHORT).show();
                    }else {
                        Toast.makeText(getApplicationContext(),"led1 off",Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.led2:
                    isChecked = led2.isChecked();
                    if (isChecked){
                        Toast.makeText(getApplicationContext(),"led2 on",Toast.LENGTH_SHORT).show();
                    }else {
                        Toast.makeText(getApplicationContext(),"led2 off",Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.led3:
                    isChecked = led3.isChecked();
                    if (isChecked){
                        Toast.makeText(getApplicationContext(),"led3 on",Toast.LENGTH_SHORT).show();
                    }else {
                        Toast.makeText(getApplicationContext(),"led3 off",Toast.LENGTH_SHORT).show();
                    }
                    break;
                case R.id.led4:
                    isChecked = led4.isChecked();
                    if (isChecked){
                        Toast.makeText(getApplicationContext(),"led4 on",Toast.LENGTH_SHORT).show();
                    }else {
                        Toast.makeText(getApplicationContext(),"led4 off",Toast.LENGTH_SHORT).show();
                    }
                    break;
            }
        }
    }
}

布局文件activity_main的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.thisway.ndkdemo.MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="ALL OFF" />

    <CheckBox
        android:id="@+id/led1"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="LED1" />
    <CheckBox
        android:id="@+id/led2"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="LED2" />
    <CheckBox
        android:id="@+id/led3"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="LED3" />
    <CheckBox
        android:id="@+id/led4"
        android:layout_marginTop="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="LED4" />

</LinearLayout>

点击菜单栏的Build→Make Project,这一步的执行为了验证工程中并无其他错误,并生成.class字节码文件,其生成的字节码文件路径为工程目录下的\build\intermediates\classes\debug文件夹下

选择View→Tool Windows→Terminal后进入命令行窗口,在AndroidStduio打开该窗口的好处是路径直接从工程目录下开始的,然后我们需要进入到main\java目录下,然后使用javah -jni com.thisway.hardcontrol.HardControl 命令,可以看到在当前目录下生成的com_thisway_hardcontrol_HardControl.h文件;内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_thisway_hardcontrol_HardControl */

#ifndef _Included_com_thisway_hardcontrol_HardControl
#define _Included_com_thisway_hardcontrol_HardControl
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_thisway_hardcontrol_HardControl
 * Method:    ledCtrl
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_thisway_hardcontrol_HardControl_ledCtrl
  (JNIEnv *, jclass, jint, jint);

/*
 * Class:     com_thisway_hardcontrol_HardControl
 * Method:    ledOpen
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_com_thisway_hardcontrol_HardControl_ledOpen
  (JNIEnv *, jclass);

/*
 * Class:     com_thisway_hardcontrol_HardControl
 * Method:    ledClose
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_thisway_hardcontrol_HardControl_ledClose
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

在工程的main目录下新建一个名字为jni的目录,然后将刚才的 .h文件剪切到里面。在jni目录下新建一个c文件,取名HardControl.c 。然后编辑代码如下:

//
// Created by Administrator on 2017/6/10.
//
#include "com_thisway_hardcontrol_HardControl.h"
#include <android/log.h>

#define  LOG_TAG    "caihaitao"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

JNIEXPORT jint JNICALL Java_com_thisway_hardlibrary_HardControl_ledCtrl
(JNIEnv *env, jclass clazz, jint which, jint status)
{
    LOGI("ledCtrl %d, %d", which, status);
    return 0;
}

JNIEXPORT jint JNICALL Java_com_thisway_hardlibrary_HardControl_ledOpen
  (JNIEnv *env, jclass clazz)
{
    LOGI("ledOpen");
    return 0;
}

JNIEXPORT void JNICALL Java_com_thisway_hardlibrary_HardControl_ledClose
  (JNIEnv *env, jclass clazz)
{
    LOGI("ledClose");
}

接下来在app module目录下的build.gradle中设置库文件名(生成的so文件名)。找到gradle文件的defaultConfig这项,在里面添加如下内容:

ndk {
            moduleName "hardcontrol"//指定生成的so文件名
            abiFilters "armeabi", "armeabi-v7a", "x86"//cpu的类型
            ldLibs "log"  //使用的链接库
    }

在工程目录下的gradle.properties文件末尾加上android.useDeprecatedNdk=true;

执行Build->Rebuild Project 验证工程中有无其他错误;

可以看到在\build\intermediates\ndk\debug\lib文件夹下生成三个文件夹,和不同的cpu对应;生成libhardcontrol.so文件;

将\build\intermediates\ndk\debug\lib文件夹拷贝到main目录下;接下来在app module目录下的build.gradle中设置.so文件的位置:

sourceSets {
    main {
        jniLibs.srcDirs = ['src/main/lib']
    }
}

现在可以点击运行app按钮。

转载于:https://my.oschina.net/cht2000/blog/917525

相关文章:

  • Foreman 1.15.1 发布,数据中心生命周期管理工具
  • C学习-枚举(九)
  • 关于网易云音乐爬虫的api接口?
  • 设计模式(一)----工厂模式
  • java 基础2
  • SQLSERVER 2008 编辑所有或者任意行
  • SpringMVC接收集合页面参数
  • JSR 303 - Bean Validation 简单介绍及用法
  • mysql5.6.36简单配置主从复制
  • 安装Discuz
  • 玩转Android Camera开发(三):国内首发---使用GLSurfaceView预览Camera 基础拍照demo
  • 学习笔记-RTOS任务创建
  • man syslog | col -b syslog.txt
  • python---数据类型---字典
  • 逆向及修复最新iOS版少数派客户端的闪退bug
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • AHK 中 = 和 == 等比较运算符的用法
  • ECMAScript入门(七)--Module语法
  • IOS评论框不贴底(ios12新bug)
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • javascript 总结(常用工具类的封装)
  • Less 日常用法
  • mysql_config not found
  • oschina
  • 力扣(LeetCode)21
  • 如何设计一个比特币钱包服务
  • 什么软件可以剪辑音乐?
  • 数组大概知多少
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (AngularJS)Angular 控制器之间通信初探
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (循环依赖问题)学习spring的第九天
  • ..回顾17,展望18
  • .NET Standard 的管理策略
  • .NET 读取 JSON格式的数据
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
  • .net解析传过来的xml_DOM4J解析XML文件
  • .sh
  • [1]-基于图搜索的路径规划基础
  • [AIGC] Spring Interceptor 拦截器详解
  • [Big Data - Kafka] kafka学习笔记:知识点整理
  • [bzoj 3124][sdoi 2013 省选] 直径
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • [C++]四种方式求解最大子序列求和问题
  • [javascript]Tab menu实现
  • [LitCTF 2023]Http pro max plus
  • [LLM]大模型八股知识点(一)
  • [Web开发] IE 所有版本打包下载,网页兼容测试必备
  • [Windows编程] DLL_THREAD_DETACH 认识误区
  • [Windows编程] C++中 bool,BOOL ,VARIANT_BOOL 的区别