Android 相关七种 CPU 架构适配

姓名:郭佳朋   学号:14310116045

转载自:http://blog.csdn.net/kester_/article/details/71055901

【嵌牛导读】:NDK 开发时会涉及到 CPU 架构的适配,不同的机器上可能会有不同的 CPU 架构,也就是说,翻译到机器上使用的规则不一样,Android 上有7种 CPU 架构。

【嵌牛鼻子】:CPU架构

【嵌牛提问】: 了解CPU相关吗?

【嵌牛正文】:安卓CPU基础

凡是接触过安卓系统的朋友,对CPU一定不会陌生。

NDK 开发时会涉及到 CPU 架构的适配,不同的机器上可能会有不同的 CPU 架构,也就是说,翻译到机器上使用的规则不一样,Android 上有7种 CPU 架构。

1.armeabi

2.armeabi-v7a

3.arm64-v8a

4.x86

5.x86_64

6.MIPS

7.MIPS64

从厂家上来分是有三种,arm,x86,MIPS,arm 系列是绝大多数手机上使用的,x86 主要是运用在平板上,而 MIPS 基本上就没见过。

从类型来分,有32位和64位,名字中没有64的就是32位的了。

正常来说只使用 armeabi-v7a 就可以适配基本所有手机了,因为现在手机基本上都支持这种CPU架构,但是对于同时也能支持 arm64-v8a 的手机来说,性能上就不如使用对应 CPU 架构的快了,毕竟是32位和64位的区别,值得一提的是,arm 系列本身是没有64位,而是 intel 的x86_64先出现的,之后 arm 收购了 MIPS64,基于 MIPS64 改良出 arm64-v8a,所以也能理解为什么 MIPS 几乎没有,而另外,arm64-v8a 的 CPU 架构上也能运行 armeabi-v7a,为什么呢?不是64位上运行32位,而是 arm64-v8a 上本身搭载了 armeabi-v7a,所以在 arm64-v8a 上运行 armeabi-v7a 是使用32位处理的,没毛病。

如果应用中有不止一个 so,那就要注意了,如果这时你一个 so 同时支持了 armeabi-v7a 和arm64-v8a,而另一个 so 只支持了一种,那可能会运行有问题,这时要么另一个 so 也支持两种,要么把第一个 so 删掉对应目录,只支持相同的一种。

在提供支持多个 CPU 架构的 SDK 时,可以同时提供多个目录的 so,虽然此时 SDK 相对较大,但是被编译的 so 还是以你在 gradle 里设置的支持的 ndk 为准:

ndk {

abiFilters ‘armeabi-v7a’ // , ‘arm64-v8a’, ‘x86’, ‘x86_64’

}

查看设备支持的 CPU 架构或者 APP 提供的 CPU 架构可以使用 Native Libs Monitor。

1 查看手机CPU信息

cmd——adb shell——cd /proc------cat cpuinfo


2 获取cpu的是arm指令集,armv7指令集、还是neon指令集

[java] view plain copy

/*** * [获取cpu类型和架构]* * @return 

* 三个参数类型的数组,第一个参数标识是不是ARM架构,第二个参数标识是V6还是V7架构,第三个参数标识是不是neon指令集

*/ 

public static Object[] getCpuArchitecture() { 

    if ((Integer) mArmArchitecture[1] != -1) { 

        return mArmArchitecture; 

    } 

    try { 

        InputStream is = new FileInputStream("/proc/cpuinfo"); 

        InputStreamReader ir = new InputStreamReader(is); 

        BufferedReader br = new BufferedReader(ir); 

        try { 

            String nameProcessor = "Processor"; 

            String nameFeatures = "Features"; 

            String nameModel = "model name"; 

            String nameCpuFamily = "cpu family"; 

            while (true) { 

                String line = br.readLine(); 

                String[] pair = null; 

                if (line == null) { 

                    break; 

                } 

                pair = line.split(":"); 

                if (pair.length != 2) 

                    continue; 

                String key = pair[0].trim(); 

                String val = pair[1].trim(); 

                if (key.compareTo(nameProcessor) == 0) { 

                    String n = ""; 

                    for (int i = val.indexOf("ARMv") + 4; i < val.length(); i++) { 

                        String temp = val.charAt(i) + ""; 

                        if (temp.matches("\\d")) { 

                            n += temp; 

                        } else { 

                            break; 

                        } 

                    } 

                    mArmArchitecture[0] = "ARM"; 

                    mArmArchitecture[1] = Integer.parseInt(n); 

                    continue; 

                } 


                if (key.compareToIgnoreCase(nameFeatures) == 0) { 

                    if (val.contains("neon")) { 

                        mArmArchitecture[2] = "neon"; 

                    } 

                    continue; 

                } 


                if (key.compareToIgnoreCase(nameModel) == 0) { 

                    if (val.contains("Intel")) { 

                        mArmArchitecture[0] = "INTEL"; 

                        mArmArchitecture[2] = "atom"; 

                    } 

                    continue; 

                } 


                if (key.compareToIgnoreCase(nameCpuFamily) == 0) { 

                    mArmArchitecture[1] = Integer.parseInt(val); 

                    continue; 

                } 

            } 

        } finally { 

            br.close(); 

            ir.close(); 

            is.close(); 

        } 

    } catch (Exception e) { 

        e.printStackTrace(); 

    } 


    return mArmArchitecture; 

调用的该函数的示例方法

[java] view plain copy

/*

* 获取FFpeg解码库的名称(如果是插件,会涉及到一个向下兼容的问题,例如:如果当前cpu是V7neo,而又没有neon的解码库,必须要做向下兼容出来

* ,如果有V7的库就加载V7的库,有V6的库就加载V6的)

*/ 

public static String getFFmpegLibName(Context context) { 

    if (LIB_FFMPEG_NAME != null) { 

        return LIB_FFMPEG_NAME; 

    } 

    Object[] arch = getCpuArchitecture(); 


    String libDir = getNativeLibraryDir(context); 

    String libSysDir = "/system/lib"; 


    if ("ARM".equals(arch[0])) { 

        try { 

            String ffmpeg = String.format("ffmpeg-%d%s", (Integer) arch[1], (String) arch[2]); 

            if (isFileExist(libDir + "/lib" + ffmpeg + ".so") || isFileExist(libSysDir + "/lib" + ffmpeg + ".so")) { 

                return ffmpeg; 

            } else { 

                boolean isV7NeonCpu = "neon".equals(arch[2]); 

                boolean isV7 = ((Integer) arch[1]) == 7 && "".equals(arch[2]); 

                boolean isV6 = ((Integer) arch[1]) == 6; 

                if (isV7NeonCpu) { 

                    if (isFileExist(libDir + "/libffmpeg-7neon.so") 

                            || isFileExist(libSysDir + "/libffmpeg-7neon.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-7neon"; 

                        return "ffmpeg-7neon"; 

                    } else if (isFileExist(libDir + "/libffmpeg-7.so") 

                            || isFileExist(libSysDir + "/libffmpeg-7.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-7"; 

                        return "ffmpeg-7"; 

                    } else if (isFileExist(libDir + "/libffmpeg-6.so") 

                            || isFileExist(libSysDir + "/libffmpeg-6.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-6"; 

                        return "ffmpeg-6"; 

                    } 

                } else if (isV7) { 

                    if (isFileExist(libDir + "/libffmpeg-7.so") || isFileExist(libSysDir + "/libffmpeg-7.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-7"; 

                        return "ffmpeg-7"; 

                    } else if (isFileExist(libDir + "/libffmpeg-6.so") 

                            || isFileExist(libSysDir + "/libffmpeg-6.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-6"; 

                        return "ffmpeg-6"; 

                    } 

                } else if (isV6) { 

                    if (isFileExist(libDir + "/libffmpeg-6.so") || isFileExist(libSysDir + "/libffmpeg-6.so")) { 

                        LIB_FFMPEG_NAME = "ffmpeg-6"; 

                        return "ffmpeg-6"; 

                    } 

                } 

            } 

        } catch (Exception e) { 

            e.printStackTrace(); 

        } 

    } else if ("INTEL".equals(arch[0])) { 

        if (isFileExist(libDir + "/libffmpeg-x86atom.so") || isFileExist(libSysDir + "/libffmpeg-x86atom.so")) { 

            LIB_FFMPEG_NAME = "ffmpeg-x86atom"; 

            return "ffmpeg-x86atom"; 

        } 

    } 

    LIB_FFMPEG_NAME = null; 

    return null; 

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容