先实现HIDL,打通从HAL到framework层

可以把自己的HIDL模块建立在hardware/interfaces/、frameworks/hardware/interfaces/、 system/hardware/interfaces/、 system/libhidl/transport/ 或者是vendor//proprietary/hardware/interfaces/等目录下。

建立HIDL目录:

$ mkdir -p hardware/interfaces/hidl_test/submodule_1/1.0/

那么这个HIDL的package name 应该是 android.hardware.hidl_test.submodule_1@1.0

建立HIDL方式的核心hal文件:

$ vi hardware/interfaces/hidl_test/submodule_1/1.0/IHidlTest.hal

package android.hardware.hidl_test.submodule_1@1.0;

interface IHidlTest {

justTest(string name) generates (string result, EnumHidlTest value);

justTest1(EnumHidlTest name);

};

$ vi hardware/interfaces/hidl_test/submodule_1/1.0/types.hal

package android.hardware.hidl_test.submodule_1@1.0;

@export(name=”EnumHidlTest”, value_prefix=””)

enum EnumHidlTest : uint8_t {

V_TEST1 = 0,

V_TEST2 = 1,

};

利用hidl-gen工具生成Android.bp、源代码等文件:

先编译一次全部的源码,然后hidl-gen就可以用了(生成在 out/host/linux-x86/bin/hidl-gen):

$ source build/envsetup.sh

$ lunch full_ac8257_demo-userdebug

$ hidl-gen -h

生成顶级目录下的Android.bp:

$ hardware/interfaces/update-makefiles.sh

其实调用的就是hidl-gen这个命令来执行的(-Landroidbp表示Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter) :

$ hidl-gen -O “” -Landroidbp   -r android.hardware:hardware/interfaces   -r android.hidl:system/libhidl/transport   android.hardware.hidl_test.submodule_1@1.0;

查看下(因为上面hal里面有@export修饰符,所以这里gen_java_constants为true):

$ cat hardware/interfaces/hidl_test/submodule_1/1.0/Android.bp

// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {

name: “android.hardware.hidl_test.submodule_1@1.0”,

root: “android.hardware”,

vndk: {

enabled: true,

},

srcs: [

“types.hal”,

“IHidlTest.hal”,

],

interfaces: [

“android.hidl.base@1.0”,

],

types: [

“EnumHidlTest”,

],

gen_java: true,

gen_java_constants: true,

}

在default子目录生成C++实现文件:

$ hidl-gen -O “” -Lc++-impl -o $ANDROID_BUILD_TOP/hardware/interfaces/hidl_test/submodule_1/1.0/default/  -r android.hardware:hardware/interfaces   -r android.hidl:system/libhidl/transport   android.hardware.hidl_test.submodule_1@1.0;

在default子目录生成Android.bp文件,以便后面对impl源文件编译:

$ hidl-gen -O “” -Landroidbp-impl -o $ANDROID_BUILD_TOP/hardware/interfaces/hidl_test/submodule_1/1.0/default/  -r android.hardware:hardware/interfaces   -r android.hidl:system/libhidl/transport   android.hardware.hidl_test.submodule_1@1.0;

$ ll hardware/interfaces/hidl_test/submodule_1/1.0/default/

-rw-r–r– 1 shuzhiang development  993  3月 25 10:35 Android.bp

-rw-r–r– 1 shuzhiang development  826  3月 25 10:34 HidlTest.cpp

-rw-r–r– 1 shuzhiang development 1376  3月 25 10:34 HidlTest.h

添加接口哈希值到current.txt:

$ hidl-gen -L hash -r android.hardware:hardware/interfaces   -r android.hidl:system/libhidl/transport    android.hardware.hidl_test.submodule_1@1.0::types

4b8c76bc9f7dbe48c357ad5b838dbf497bd0af9c3c0ee5a557b947794abe1cd7 android.hardware.hidl_test.submodule_1@1.0::types

把上面的输出结果添加到current.txt,加到最后即可:

$ vi hardware/interfaces/current.txt

4b8c76bc9f7dbe48c357ad5b838dbf497bd0af9c3c0ee5a557b947794abe1cd7 android.hardware.hidl_test.submodule_1@1.0::types

然后可以修改HidlTest.cpp来实现接口的函数:

切记:如果hal文件变更了,重新生成该代码时,会被覆盖掉,所以每次hal变更前把default目录mv一下,换个名字,等生成完了,再把老的代码手工移到新生成的文件里面。

$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/HidlTest.cpp

#define LOG_TAG “HidlTestImpl”

#include

#include “HidlTest.h”

namespace android {

namespace hardware {

namespace hidl_test {

namespace submodule_1 {

namespace V1_0 {

namespace implementation {

// Methods from ::android::hardware::hidl_test::submodule_1::V1_0::IHidlTest follow.

Return HidlTest::justTest(const hidl_string& name, justTest_cb _hidl_cb) {

// TODO implement

ALOGD(“justTest, name = %s”, name.c_str());

_hidl_cb(name, EnumHidlTest::V_TEST2);

ALOGD(“justTest end.”);

return Void();

}

Return HidlTest::justTest1(::android::hardware::hidl_test::submodule_1::V1_0::EnumHidlTest name) {

// TODO implement

ALOGD(“justTest1, name = %hhu”, name);

return Void();

}

要把它当成service来启动,则还少一个main函数来加载,所以增加一个service.cpp:

$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/service.cpp

#define LOG_TAG “android.hardware.hidl_test.submodule_1@1.0-service”

#include

#include

#include “HidlTest.h”

// Generated HIDL files

using android::hardware::hidl_test::submodule_1::V1_0::IHidlTest;

using android::hardware::hidl_test::submodule_1::V1_0::implementation::HidlTest;

using android::hardware::defaultPassthroughServiceImplementation;

using android::hardware::configureRpcThreadpool;

using android::hardware::joinRpcThreadpool;

int main() {

#if 0

return defaultPassthroughServiceImplementation();

#else

sp service = new HidlTest();

configureRpcThreadpool(1, true /*callerWillJoin*/);

if(android::OK !=  service->registerAsService())

return 1;

joinRpcThreadpool();

#endif

}

既然是service,可以增加一个rc文件来启动它(注意和Android.bp里面的对应):

$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/android.hardware.hidl_test.submodule_1@1.0-service.rc

service hidltest /vendor/bin/hw/android.hardware.hidl_test.submodule_1@1.0-service

class hal

user system

group system

修改default下的Android.bp文件(添加service.cpp并生成可执行文件),在最前面增加整个cc_binary部分:

$ cat hardware/interfaces/hidl_test/submodule_1/1.0/default/Android.bp

cc_binary {

name: “android.hardware.hidl_test.submodule_1@1.0-service“,

defaults: [“hidl_defaults”],

relative_install_path: “hw”,

vendor: true,

init_rc: [“android.hardware.hidl_test.submodule_1@1.0-service.rc“],

srcs: [

“HidlTest.cpp”,

“service.cpp”

],

shared_libs: [

“liblog”,

“libhidlbase”,

“libhidltransport”,

“libutils”,

“libhardware”,

“android.hardware.hidl_test.submodule_1@1.0”,

],

}

记得把liblog也要加入到cc_library_shared这个模块的shared_libs部分。

插入设备的manifest.xml(autochips/ac8257_demo整个部分要根据自己实际使用的设备来定):

加到尾部之前即可:

$ vi device/autochips/ac8257_demo/manifest.xml

android.hardware.hidl_test.submodule_1

hwbinder

1.0

IHidlTest

default

加入到device.mk,以便启动service:

加到尾部即可:

$ vi device/autochips/ac8257_demo/device.mk

PRODUCT_PACKAGES += android.hardware.hidl_test.submodule_1@1.0-service

修改VNDK相关部分:

在current.txt里按字母顺序添加,否则编译不过:

$ vi build/make/target/product/vndk/current.txt

VNDK-core: android.hardware.hidl_test.submodule_1@1.0.so

在28.txt里按字母顺序添加,否则编译不过:

$ vi build/make/target/product/vndk/28.txt

VNDK-core: android.hardware.hidl_test.submodule_1@1.0.so

修改SELINUX相关,以便service能在 rc里面启动:

尾部添加:

$ vi system/sepolicy/vendor/file_contexts

/(vendor|system/vendor)/bin/hw/android\.hardware\.hidl_test\.submodule_1@1\.0-service          u:object_r:hal_test_default_exec:s0

新建文件:

$ vi system/sepolicy/vendor/hal_test_default.te

type hal_test_default, domain;

hal_server_domain(hal_test_default, hal_test)

type hal_test_default_exec, exec_type, vendor_file_type, file_type;

init_daemon_domain(hal_test_default)

相应位置添加:

$ vi system/sepolicy/public/attributes

hal_attribute(test);

尾部添加:

$ vi system/sepolicy/public/hwservice

type hal_test_hwservice, hwservice_manager_type;

新建文件:

$ vi system/sepolicy/public/hal_test.te

# HwBinder IPC from client to server, and callbacks

binder_call(hal_test_client, hal_test_server)

binder_call(hal_test_server, hal_test_client)

add_hwservice(hal_test_server, hal_test_hwservice)

allow hal_test_client hal_test_hwservice:hwservice_manager find;

和api目录同步:

$ cp system/sepolicy/public/attributes   system/sepolicy/prebuilts/api/28.0/public/

$ cp system/sepolicy/public/hwservice.te system/sepolicy/prebuilts/api/28.0/public/

$ cp system/sepolicy/public/hal_test.te  system/sepolicy/prebuilts/api/28.0/public/

最前面加一行:

$ vi system/sepolicy/private/hwservice_contexts

android.hardware.hidl_test.submodule_1::IHidlTest               u:object_r:hal_test_hwservice:s0

在new_objects里面加入:

$ vi system/sepolicy/private/compat/26.0/26.0.ignore.cil

hal_test_hwservice

$ vi system/sepolicy/private/compat/27.0/27.0.ignore.cil

hal_test_hwservice

和api目录同步:

$ cp system/sepolicy/private/compat/27.0/27.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/27.0/

$ cp system/sepolicy/private/compat/26.0/26.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/26.0/

$ cp system/sepolicy/private/hwservice_contexts system/sepolicy/prebuilts/api/28.0/private/

编译:

编译中间接口:

$ cd hardware/interfaces/hidl_test/submodule_1/1.0/

$ mm showcommands

生成的中间结果:

$ ll out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/

total 56

drwxr-xr-x 14 shuzhiang development 4096  3月 25 10:29 ./

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:16 ../

drwxr-xr-x 10 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0/

drwxr-xr-x  4 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter_genc++/

drwxr-xr-x 10 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper_genc++/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper_genc++_headers/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:16 android.hardware.hidl_test.submodule_1@1.0_genc++/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:16 android.hardware.hidl_test.submodule_1@1.0_genc++_headers/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java-constants/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java-constants_gen_java/

drwxr-xr-x  3 shuzhiang development 4096  3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/

这个接口文件做客户端时会用到:

out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/gen/android/hardware/hidl_test/submodule_1/V1_0/IHidlTest.java

编译出最终的库和service:

$ cd hardware/interfaces/hidl_test/submodule_1/1.0/default

$ mm showcommands

输出位置:

$ ll out/target/product/ac8257_demo/vendor/lib/hw/android.hardware.hidl_test.submodule_1@1.0-impl.so

$ ll out/target/product/ac8257_demo/vendor/bin/hw/android.hardware.hidl_test.submodule_1@1.0-service

$ ll out/target/product/ac8257_demo/system/etc/init/android.hardware.hidl_test.submodule_1@1.0-service.rc

因为修改了很多selinux相关的东西,最终需要整个android全部重新编译一次。

$ nohup ./allmake.sh -i &

$ tail -f nohup.out

重新烧录后,就可以看到service起来了:

# ps -Afl | grep hidl_test

system         379     1 0 23:59:04 ?     00:00:00 android.hardware.hidl_test.submodule_1@1.0-service

用AIDL来实现framework层到APP层

实现framework层的system service接口:

$ mkdir -p frameworks/base/core/java/android/os/hidltest

$ vi frameworks/base/core/java/android/os/hidltest/IHidlTestService.aidl

// IHidlTestService.aidl

package android.os.hidltest;

// Declare any non-default types here with import statements

interface IHidlTestService {

/**

* Demonstrates some basic types that you can use as parameters

* and return values in AIDL.

*/

void justTest1(int enumValue);

void justTest(String str);

}

从app getService后,调用的是该类下的函数:

$ vi frameworks/base/core/java/android/os/hidltest/HidlTestManager.java

package android.os.hidltest;

/**

* android.os.hidltest.HidlTestManager;

*

* @author

* @date

*/

import android.os.RemoteException;

import android.util.Log;

public class HidlTestManager {

private IHidlTestService mService;

public static final String TAG = “HidlTestManager”;

public HidlTestManager(IHidlTestService server) {

Log.d(TAG, “HidlTestManager”);

mService = server;

}

public void justTest1(int enumValue){

Log.d(TAG, “justTest1: enumValue: “+enumValue);

try {

if (mService != null) {

mService.justTest1(enumValue);

}

} catch (RemoteException e) {

e.printStackTrace();

}

}

public void justTest(String str){

Log.d(TAG, “justTest: str: “+str);

try {

if (mService != null) {

mService.justTest(str);

}

} catch (RemoteException e) {

e.printStackTrace();

}

}

}

添加到系统中:

$ vi frameworks/base/Android.bp

java_library {

name: “framework”,

srcs: [

下面增加:

“core/java/android/os/hidltest/IHidlTestService.aidl”,

$ vi frameworks/base/services/core/Android.bp

static_libs: [

里面定义:

“android.hardware.hidl_test.submodule_1-V1.0-java”,

定义stub类,供上面HidlTestManager.java调用,然后在这个stub里面调用底层HIDL定义的接口:

$ mkdir -p frameworks/base/services/core/java/com/android/server/hidltest

$ vi frameworks/base/services/core/java/com/android/server/hidltest/HidlTestService.java

package com.android.server.hidltest;

import android.hardware.hidl_test.submodule_1.V1_0.IHidlTest;

import android.os.RemoteException;

import android.util.Log;

import android.os.hidltest.IHidlTestService;

import java.util.ArrayList;

/**

* com.android.server.hidltest.HidlTestService

*

* @author

* @date

*/

public class HidlTestService extends IHidlTestService.Stub {

private String TAG = “HidlTestService”;

private IHidlTest halService ;

public HidlTestService(){

try {

halService = IHidlTest.getService();//get service

} catch (RemoteException e) {

e.printStackTrace();

}

}

@Override

public void justTest1(int enumValue){

Log.d(TAG, “justTest1: enumValue: “+enumValue);

try{

halService.justTest1((byte)enumValue);

} catch (RemoteException e) {

e.printStackTrace();

}

}

//justTestCallback: produce by HIDL interface, refer to “out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/gen/android/hardware/hidl_test/submodule_1/V1_0/IHidlTest.java”

public void justTest(String str){

Log.d(TAG, “justTest: str: “+str);

android.os.HwParcel _hidl_reply = new android.os.HwParcel();

IHidlTest.justTestCallback aaa = new IHidlTest.justTestCallback() {

@Override

public void onValues(String result, byte value) {

_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);

_hidl_reply.writeString(result);

_hidl_reply.writeInt8(value);

_hidl_reply.send();

}

};

try{

halService.justTest(str, aaa);

} catch (RemoteException e) {

e.printStackTrace();

}

}

}

$ vi frameworks/base/core/java/android/content/Context.java

@StringDef(suffix = { “_SERVICE” }, value = {

里面增加:

HIDLTEST_SERVICE,

然后在下面其他SERVICE定义位置平行添加一个成员变量:

/**

* {@link android.os.hidltest.HidlTestManager} for receiving intents at a

* time of your choosing.

*

* @see #getSystemService

* @see android.os.hidltest.HidlTestManager

*/

public static final String HIDLTEST_SERVICE = “hidltest”;

$ vi frameworks/base/core/java/android/app/SystemServiceRegistry.java

在import部分增加:

import android.os.hidltest.HidlTestManager;

import android.os.hidltest.IHidlTestService;

在SystemServiceRegistry类的static { 下面添加:

registerService(Context.HIDLTEST_SERVICE, HidlTestManager.class,

new CachedServiceFetcher() {

@Override

public HidlTestManager createService(ContextImpl ctx) {

IBinder iBinder = ServiceManager.getService(Context.HIDLTEST_SERVICE);

if (iBinder == null) {

return null;

}

IHidlTestService service = IHidlTestService.Stub.asInterface(iBinder);

return new HidlTestManager(service);

}});

$ vi frameworks/base/services/java/com/android/server/SystemServer.java

在import部分增加:

import com.android.server.hidltest.HidlTestService;

在startOtherServices函数体的}, SECONDARY_ZYGOTE_PRELOAD); 后面增加:

try {

Slog.i(TAG, “hidltest Service”);

ServiceManager.addService(Context.HIDLTEST_SERVICE, new HidlTestService());

} catch (Throwable e) {

reportWtf(“starting HidlTestService”, e);

}

添加selinux的策略:

$ vi system/sepolicy/public/service.te

尾部添加(hidltest_service这个类型给后面private里面用):

type hidltest_service, system_api_service, system_server_service, service_manager_type;

和api目录同步:

$ cp system/sepolicy/public/service.te system/sepolicy/prebuilts/api/28.0/public/

$ vi system/sepolicy/private/service_contexts

顶部添加(hidltest这个要和frameworks/base/core/java/android/content/Context.java里面HIDLTEST_SERVICE = “hidltest”;的hidltest一致):

hidltest                                 u:object_r:hidltest_service:s0

$ vi system/sepolicy/private/system_server.te

在hal_client_domain部分添加(hal_test为之前定义过的hal_test.te):

hal_client_domain(system_server, hal_test)

$ vi system/sepolicy/private/compat/26.0/26.0.ignore.cil

在(typeattributeset new_objects里面添加:

hidltest_service

$ vi system/sepolicy/private/compat/27.0/27.0.ignore.cil

在(typeattributeset new_objects里面添加:

hidltest_service

和api目录同步:

$ cp system/sepolicy/private/service_contexts system/sepolicy/prebuilts/api/28.0/private/

$ cp system/sepolicy/private/system_server.te system/sepolicy/prebuilts/api/28.0/private/

$ cp system/sepolicy/private/compat/26.0/26.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/26.0/

$ cp system/sepolicy/private/compat/27.0/27.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/27.0/

重新生成image,并且生成sdk(新的sdk要能再板上用,需要重新烧录新编译的image):

必须做,否则报api没更新的错:

$ source build/envsetup.sh

$ lunch full_ac8257_demo-userdebug

$ make update-api

重新登录编译系统:

$ nohup ./allmake.sh -i &

重新生成sdk库:

$ ./allmake.sh sdklibs

生成位置: ac8257-androidP/sdklibs/

然后可以建立新的android studio 3.5的app

把生成的framework_classes.jar 放到 app/libs目录下。

然后源文件中可以导入以下类文件了:

android.os.hidltest.HildTestManager

然后需要优先使用framework_classes.jar里面的类,而不是android studio默认的sdk类,在app目录下面的build.gradle尾部增加(实际就是把app.iml文件的这一行挪到其尾部):

preBuild {

doLast {

def imlFile = file(project.name + “.iml”)

println ‘Change ‘ + project.name + ‘.iml order’

try {

def parsedXml = (new XmlParser()).parse(imlFile)

def jdkNode = parsedXml.component[1].orderEntry.find { it.’@type’ == ‘jdk’ }

parsedXml.component[1].remove(jdkNode)

def sdkString = “Android API ” + android.compileSdkVersion.substring(“android-“.length()) + ” Platform”

new Node(parsedXml.component[1], ‘orderEntry’, [‘type’: ‘jdk’, ‘jdkName’: sdkString, ‘jdkType’: ‘Android SDK’])

groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))

} catch (FileNotFoundException e) {

}

}

}

修改最外层的build.gradle:

在allprojects里面增加:

// 添加下面代码,加入编译参数,只编译,不打包

gradle.projectsEvaluated {

tasks.withType(JavaCompile) {

options.compilerArgs << ‘-Xbootclasspath/p:app/libs/framework_classes.jar’

}

}

修改app目录下的build.gradle:

在dependencies部分修改:

//implementation fileTree(dir: ‘libs’, include: [‘*.jar’])

compileOnly files(‘libs/framework_classes.jar’) //只编译,不打包

修改MainActivity.java的代码:

public class MainActivity extends AppCompatActivity {

HidlTestManager mTestManager;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mTestManager = (HidlTestManager)getSystemService(Context.HIDLTEST_SERVICE);

mTestManager.justTest1(1);

mTestManager.justTest(“name=APP:HIDL_client_test”);

}

}

运行起来的输出(justTest函数调用到hardware层的service时会导致问题,后续需要调试修改,所以尽量少使用generates多个返回值的HIDL):

2020-03-26 13:16:09.528 24582-24582/com.maxshu.hidl_client_test D/HidlTestManager: HidlTestManager

2020-03-26 13:16:09.528 24582-24582/com.maxshu.hidl_client_test D/HidlTestManager: justTest1: enumValue: 1

2020-03-26 13:16:09.528 15035-15035/com.maxshu.hidl_client_test D/HidlTestManager: HidlTestManager

2020-03-26 13:16:09.528 15035-15035/com.maxshu.hidl_client_test D/HidlTestManager: justTest: str: name=APP:HIDL_client_test

aidl android 怎么mk编译,使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序相关推荐

  1. android studio 反编译工具,android studio反编译工具jd-inteIIij

    Android Studio 自带了Java Bytecode Decompiler 对于第三方的jar只能反编译出其函数名 例如:andbase里的com.kfb.c.jar下的com.kfb.c下 ...

  2. android so 不能编译进,Android Studio下编译LatinIME so库CMake版

    编译环境 Android Studio 3.1.3 gradle 4.4-all cmake (sdk目录下) ndk-bundle (sdk目录下) 源码 Android 8.1 (1) packa ...

  3. android中ndk编译错误,Android NDK编译常见错误及解决方案

    Android NDK编译常见错误及解决方案 Error 1:$ ndk-build/cygdrive/c/andy/abc/obj/local/armeabi-v7a/objs/abc//hello ...

  4. android ffmegp for_FFmpeg 编译for Android

    编译环境: debian x64 ndk-r14b 1. 安装ndk-r14b 下载地址 http://mirrors.neusoft.edu.cn/android/repository/androi ...

  5. android 模块不编译错误,Android 编译出错版本匹配问题解决办法

    Android 编译出错版本匹配问题解决办法 解决问题的关键在于版本匹配, compileSdkVersion compileSdkVersion targetSdkVersion 这三个参数的整数值 ...

  6. 自己写的android apk反编译,获取Android自己写好了的apk以及反编译

    今天,我们先说一下,获取Android自带的apk以及反编译它们来学习Android工程师是怎样写的,今天我们就以拿到Android自带的短信管理器的apk为例子 你可能有疑问,为什么要那么麻烦,从系 ...

  7. [Android Pro] 告别编译运行 ---- Android Studio 2.0 Preview发布Instant Run功能

    reference to : http://www.cnblogs.com/soaringEveryday/p/4991563.html 以往的Android开发有一个头疼的且拖慢速度的问题,就是你每 ...

  8. 简述android源代码的编译过程,Android源码编译过程详述

    首先说一下,编译Android所用的系统,目前ubuntu是比较好的平台,也是官方推荐的,但具体版本,说的都比较少,为了避免大家走弯路,我 这里说一下,最好的就是ubuntu 8.10,他所带有的各个 ...

  9. android studio如何编译测试,Android Studio 进行单元测试完整教程

    前言 为了这个AndroidStudio的单元测试,从下午搞到晚上才搞明白咋操作. 我学一个新知识总是那么坎坷,经历无数的错误路径,才可能找到正确的路在哪儿. 我的AndroidStudio 我的An ...

最新文章

  1. react-native 查看对象属性
  2. e.printStackTrace()会导致锁死?这仅仅是打印,怎么可能?
  3. php扩展包是什么意思,php – 扩展或包括 – 什么是更好的Twig?
  4. net start mysql 发生系统错误 5。 拒绝访问。
  5. I/O设备的编址方式(统一编址,独立编址)
  6. java 超时异常_Java如何实现任务超时处理
  7. Ubuntu下deb与rpm包的安装方法
  8. 10-10-009-简介-常用Message Queue对比
  9. android app开发计划
  10. codeforces1467E. Distinctive Roots in a Tree
  11. TIA protal与SCL从入门到精通(6):示例一 获取本地时间与定时开关(不用计时器)
  12. CKEditor编辑器的详细使用
  13. 哔哩哔哩20校招算法笔试题(2019.8.20)第二道编程题 AC
  14. IT人士之成功磨难记
  15. java模仿微信QQ群聊头像拼接,根据群聊内的用户头像拼接群聊头像,九宫格
  16. 皕杰报表自定义扩展~自定义数据集
  17. 【MySQL存储过程】光标的使用详解
  18. 魔百和CM311-1a_CH_S905L3A_安卓9.0_纯净线刷固件包
  19. oracle amm和asmm,在Oracle中,什么是ASMM和AMM?
  20. 计算机硬件的联通,联通4g支撑系统介绍_计算机硬件及收集_it计算机_专业资料[精彩].ppt...

热门文章

  1. 2022/10/26 OR 27 关于java的接口初识 猫狗接口/教练学员案例
  2. 自己开发了一个财神小童子合成
  3. 使用poi操作excel详解
  4. ansible_unarchive/tar 解压文件时去除层级目录
  5. CentOS7-Nginx反向代理
  6. DataGridView 选中一行后,保持前景色(颜色,字体)不变
  7. linux查找文件并删除
  8. 疫苗之王的发家之路《转载》
  9. 支付宝 php rsa2,#支付宝 RSA2和公钥证书签名验签的区别?
  10. 星淘惠跨境—长三角跨境电商行业发展峰会助推跨境电商发展