2024年Android最新第一章:android串口开发so库生成,2024年最新一线互联网企业高级Android工程师面试题大全

最后

在此为大家准备了四节优质的Android高级进阶视频:

架构师项目实战——全球首批Android开发者对Android架构的见解

附相关架构及资料

image.png

往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

#include “android/log.h”

static const char *TAG=“serial_port”;

#define LOGI(fmt, args…) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, ##args)

#define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)

#define LOGE(fmt, args…) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)

static speed_t getBaudrate(jint baudrate)

{

switch(baudrate) {

case 0: return B0;

case 50: return B50;

case 75: return B75;

case 110: return B110;

case 134: return B134;

case 150: return B150;

case 200: return B200;

case 300: return B300;

case 600: return B600;

case 1200: return B1200;

case 1800: return B1800;

case 2400: return B2400;

case 4800: return B4800;

case 9600: return B9600;

case 19200: return B19200;

case 38400: return B38400;

case 57600: return B57600;

case 115200: return B115200;

case 230400: return B230400;

case 460800: return B460800;

case 500000: return B500000;

case 576000: return B576000;

case 921600: return B921600;

case 1000000: return B1000000;

case 1152000: return B1152000;

case 1500000: return B1500000;

case 2000000: return B2000000;

case 2500000: return B2500000;

case 3000000: return B3000000;

case 3500000: return B3500000;

case 4000000: return B4000000;

default: return -1;

}

}

static void throwException(JNIEnv *env, const char *name, const char *msg)

{

jclass cls = env->FindClass(name);

/* if cls is NULL, an exception has already been thrown */

if (cls != NULL) {

env->ThrowNew(cls, msg);

}

/* free the local ref */

env->DeleteLocalRef(cls);

}

extern “C”

JNIEXPORT jobject JNICALL Java_cn_yumakeji_lib_1serialportapi_SerialPort_open__Ljava_lang_String_2IIIII

(JNIEnv *env, jclass thiz, jstring path, jint baudrate,jint parity, jint dataBits, jint stopBit, jint flags)

{

int fd;

speed_t speed;

jobject mFileDescriptor;

/* Check arguments */

{

speed = getBaudrate(baudrate);

if (speed == -1) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid baudrate”);

return NULL;

}

if (parity <0 || parity>2) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid parity”);

return NULL;

}

if (dataBits <5 || dataBits>8) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid dataBits”);

return NULL;

}

if (stopBit <1 || stopBit>2) {

throwException(env, “java/lang/IllegalArgumentException”, “Invalid stopBit”);

return NULL;

}

}

/* Opening device */

{

jboolean iscopy;

const char *path_utf = env->GetStringUTFChars(path, &iscopy);

LOGD(“Opening serial port %s with flags 0x%x”, path_utf, O_RDWR | flags);

fd = open(path_utf, O_RDWR | flags);

LOGD(“open() fd = %d”, fd);

env->ReleaseStringUTFChars(path, path_utf);

if (fd == -1)

{

throwException(env, “java/io/IOException”, “Cannot open port”);

return NULL;

}

}

/* Configure device */

{

struct termios cfg;

LOGD(“Configuring serial port”);

if (tcgetattr(fd, &cfg))

{

LOGE(“tcgetattr() failed”);

close(fd);

throwException(env, “java/io/IOException”, “tcgetattr() failed”);

return NULL;

}

cfmakeraw(&cfg);

cfsetispeed(&cfg, speed);

cfsetospeed(&cfg, speed);

/* More attribute set */

switch (parity) {

case 0: break;

case 1: cfg.c_cflag |= PARENB; break;

case 2: cfg.c_cflag &= ~PARODD; break;

}

switch (dataBits) {

case 5: cfg.c_cflag |= CS5; break;

case 6: cfg.c_cflag |= CS6; break;

case 7: cfg.c_cflag |= CS7; break;

case 8: cfg.c_cflag |= CS8; break;

}

switch (stopBit) {

case 1: cfg.c_cflag &= ~CSTOPB; break;

case 2: cfg.c_cflag |= CSTOPB; break;

}

if (tcsetattr(fd, TCSANOW, &cfg))

{

LOGE(“tcsetattr() failed”);

close(fd);

/* TODO: throw an exception */

return NULL;

}

}

/* Create a corresponding file descriptor */

{

jclass cFileDescriptor = env->FindClass(“java/io/FileDescriptor”);

jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor, “”, “()V”);

jfieldID descriptorID = env->GetFieldID(cFileDescriptor, “descriptor”, “I”);

mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor);

env->SetIntField(mFileDescriptor, descriptorID, (jint)fd);

}

return mFileDescriptor;

}

/*

  • Class: android_serialport_SerialPort

  • Method: open

  • Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;

*/

JNIEXPORT jobject JNICALL Java_cn_yumakeji_lib_1serialportapi_SerialPort_open__Ljava_lang_String_2II

(JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)

{

int fd;

speed_t speed;

jobject mFileDescriptor;

/* Check arguments */

{

speed = getBaudrate(baudrate);

if (speed == -1) {

/* TODO: throw an exception */

LOGE(“Invalid baudrate”);

return NULL;

}

}

/* Opening device */

{

jboolean iscopy;

const char *path_utf = env->GetStringUTFChars(path, &iscopy);

LOGD(“Opening serial port %s with flags 0x%x”, path_utf, O_RDWR | flags);

fd = open(path_utf, O_RDWR | flags);

LOGD(“open() fd = %d”, fd);

env->ReleaseStringUTFChars(path, path_utf);

if (fd == -1)

{

/* Throw an exception */

throwException(env, “java/io/IOException”, “Cannot open port”);

/* TODO: throw an exception */

return NULL;

}

}

/* Configure device */

{

struct termios cfg;

LOGD(“Configuring serial port”);

if (tcgetattr(fd, &cfg))

{

LOGE(“tcgetattr() failed”);

close(fd);

/* TODO: throw an exception */

return NULL;

}

cfmakeraw(&cfg);

cfsetispeed(&cfg, speed);

cfsetospeed(&cfg, speed);

if (tcsetattr(fd, TCSANOW, &cfg))

{

LOGE(“tcsetattr() failed”);

close(fd);

/* TODO: throw an exception */

return NULL;

}

}

/* Create a corresponding file descriptor */

{

jclass cFileDescriptor = env->FindClass(“java/io/FileDescriptor”);

jmethodID iFileDescriptor = env->GetMethodID(cFileDescriptor, “”, “()V”);

jfieldID descriptorID = env->GetFieldID(cFileDescriptor, “descriptor”, “I”);

mFileDescriptor = env->NewObject(cFileDescriptor, iFileDescriptor);

env->SetIntField( mFileDescriptor, descriptorID, (jint)fd);

}

return mFileDescriptor;

}

/*

  • Class: cedric_serial_SerialPort

  • Method: close

  • Signature: ()V

*/

JNIEXPORT void JNICALL Java_cn_yumakeji_lib_1serialportapi_SerialPort_close

(JNIEnv *env, jobject thiz)

{

jclass SerialPortClass = env->GetObjectClass( thiz);

jclass FileDescriptorClass = env->FindClass(“java/io/FileDescriptor”);

jfieldID mFdID = env->GetFieldID( SerialPortClass, “mFd”, “Ljava/io/FileDescriptor;”);

jfieldID descriptorID = env->GetFieldID( FileDescriptorClass, “descriptor”, “I”);

jobject mFd = env->GetObjectField( thiz, mFdID);

jint descriptor = env->GetIntField( mFd, descriptorID);

LOGD(“close(fd = %d)”, descriptor);

close(descriptor);

}

  • 修改mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

TARGET_PLATFORM := android-16

LOCAL_CPP_EXTENSION := cpp #代表c++文件的扩展名可以随意 一般是cpp

LOCAL_MODULE := serial_port

#LOCAL_SRC_FILES := SerialPort.c #进行C语言编码

LOCAL_SRC_FILES := SerialPort.cpp #进行cpp进行编码

LOCAL_LDLIBS := -llog

#libxxx.so- text relocations问题的终极解决方案

LOCAL_LDFLAGS += -fPIC

include $(BUILD_SHARED_LIBRARY)

#APP_ABI := armeabi armeabi-v7a x86

APP_ABI := all

  • 在jni目录下编译生成so库

在这里插入图片描述

  • 然后将so库拷贝到jniLibs目录下使用

  • 配置gradle

sourceSets {

main() {

jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程

文末

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

714978495662)]

【算法合集】

[外链图片转存中…(img-FA0JhNhm-1714978495662)]

【延伸Android必备知识点】

[外链图片转存中…(img-cCVgBAyY-1714978495663)]

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值