Android VLC播放器二次开发2——CPU类型检查+界面初始化

2023-11-05

上一篇讲了VLC整个程序的模块划分和界面主要使用的技术,今天分析一下VLC程序初始化过程,主要是初始化界面、加载解码库的操作。今天主要分析一下org.videolan.vlc.gui.MainActivity类,这个是VLC的整个程序入口。当然,严格来说,整个程序入口是VLCApplication类,因为VLC重载了Application,在我分析过的代码里面,貌似稍微复杂一点的程序,都喜欢重载Application。我自己写的一些程序也喜欢重载Application,因为可以提供一些全局功能和方便多页面数据交互。

  给出上一篇的截图,方便后面讲解程序初始化。 

(PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)

  

1、VLCApplication类

  这里简单说一下VLCApplication,如果你对Application的作用的功能不了解,请仔细查阅相关资料,这是一个很重要知识点。VLCApplication做的事情不多,简单来说,做了两件事。第一个是一个本地配置的初始化,主要是Locale的配置,而且都是针对中文做特别处理,另外就是当系统内存不多的时候,回收一些bitmap的内存。剩下的就是保存一个全局的静态对象供其他类使用。

  本地配置初始化这里不多说,都是简单的SharedPreferences读写和Locale配置,有兴趣自己看看源码。下面给出系统内存低的时候,回收bitmap缓存。这个平时可能不会太留意。

//Edited by mythou
//http://www.cnblogs.com/mythou/
  public void onLowMemory() 
    {
        super.onLowMemory();
        Log.w(TAG, "System is running low on memory");
     //系统内存降低的时候,回收bitmap缓存
        BitmapCache.getInstance().clear();
    }

 

2、CPU类型检查

  这个功能基本上是用第三方库做解码器的,都需要做。因为我们编译FFMpeg解码库和其他解码库的时候,一般都需要指定CPU类型,例如现在的智能手机CPU架构有ARM和Intel的X86还有一些MIPS架构CPU。ARM里面又区分好几种类别。所以我们编译的时候都需要针对不同类型CPU做优化。这也导致了,我们需要检查我们的解码库跟机器的CPU类型是否匹配。

  之所以把这个能拿出来讲,是因为以后做一些跟CPU有关应用的时候,我们也需要检查CPU类型。

//Edited by mythou
//http://www.cnblogs.com/mythou/
  public static boolean hasCompatibleCPU(Context context)
    {
        if(errorMsg != null || isCompatible) return isCompatible;
     //读取VLC解码库,这一部分里面还有很多处理,下面会讲解
        ElfData elf = readLib(context.getApplicationInfo().dataDir + "/lib/libvlcjni.so");
        if(elf == null) 
        {
            Log.e(TAG, "WARNING: Unable to read libvlcjni.so; cannot check device ABI!");
            Log.e(TAG, "WARNING: Cannot guarantee correct ABI for this build (may crash)!");
            return true;
        }
     //记录CPU的类型,注意android2.2以后,会有两个CPU类型
        String CPU_ABI = android.os.Build.CPU_ABI;
        String CPU_ABI2 = "none";
        if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { // CPU_ABI2 since 2.2
            try {
                CPU_ABI2 = (String)android.os.Build.class.getDeclaredField("CPU_ABI2").get(null);
            } catch (Exception e) { }
        }
     //各种CPU参数记录,对这些不了解,可以百度一下。
        boolean hasNeon = false, hasFpu = false, hasArmV6 = false,
                hasArmV7 = false, hasMips = false, hasX86 = false;
        float bogoMIPS = -1;
        int processors = 0;
     //判断CPU的架构
        if(CPU_ABI.equals("x86")) 
        {
            hasX86 = true;
        } 
        else if(CPU_ABI.equals("armeabi-v7a") ||
                  CPU_ABI2.equals("armeabi-v7a")) 
        {
            hasArmV7 = true;
            hasArmV6 = true; /* Armv7 is backwards compatible to < v6 */
        } 
        else if(CPU_ABI.equals("armeabi") ||
                  CPU_ABI2.equals("armeabi"))
        {
            hasArmV6 = true;
        }
      
     //......下面还有一些CPU参数识别,这里就省略了
     //把CPU参数保存起来
        machineSpecs = new MachineSpecs();
        machineSpecs.hasArmV6 = hasArmV6;
        machineSpecs.hasArmV7 = hasArmV7;
        machineSpecs.hasFpu = hasFpu;
        machineSpecs.hasMips = hasMips;
        machineSpecs.hasNeon = hasNeon;
        machineSpecs.hasX86 = hasX86;
        machineSpecs.bogoMIPS = bogoMIPS;
        machineSpecs.processors = processors;
        return true;
    }

   上面的CPU参数属性里面说到了好几种参数,如果你对ARM不了解,建议百度查一下。这里简单讲解一下ABI,CPU_ABI是我们经常都会碰见的,例如我们在Android工程里面的libs库下面就有armeabi-v7a类型的库。这里的ABI是指Application Binary Interface。

  ABI描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低层接口。ABI不同于应用程序接口(API),API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。

  ABI掩盖了各种细节,例如:调用约定(控制着函数的参数如何传送以及如何接受返回值);系统调用的编码和一个应用如何向操作系统进行系统调用;以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库等等。一个完整的ABI,像Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作体统上运行。其他的 ABI 标准化细节包括 C++ name decoration 和同一个平台上的编译器之间的调用约定,但是不包括跨平台的兼容性。

  简单的说,ABI规范了应用程序对寄存器的使用方法,Call procedure,以及如何进入trap。符合某一平台ABI规范的应用程序就可以在这一平台上运行。这一规范是针对binary,而不是source的。所以同样的高级语言代码,使用不同的toolchain,可以得到符合不同ABI规范的binary。

  至于其他参数,如果有不清楚,请百度一下,其他参数比较好理解,这里不多说。

 

3、VLCLib解码库初始化

//Edited by mythou
//http://www.cnblogs.com/mythou/
  static {
        try {
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1)
                System.loadLibrary("iomx-gingerbread");  //第一个解码库
            else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2)
                System.loadLibrary("iomx-hc");  //第二个解码库
            else
                System.loadLibrary("iomx-ics");  //第三个解码库
        } catch (Throwable t) {
            Log.w(TAG, "Unable to load the iomx library: " + t);
        }
        try {
            System.loadLibrary("vlcjni");  //第四个解码库
        } catch (UnsatisfiedLinkError ule) {
            Log.e(TAG, "Can't load vlcjni library: " + ule);
            /// FIXME Alert user
            System.exit(1);
        } catch (SecurityException se) {
            Log.e(TAG, "Encountered a security issue when loading vlcjni library: " + se);
            /// FIXME Alert user
            System.exit(1);
        }
    }

  解码库初始化没有什么特别,这里主要是想讲讲VLC用到的解码库总共有4个,都是在LibVLC.java类里面的静态代码块加载。至于每个解码库具体作用,还没有仔细分析,后面分析清楚再说。

 

4、界面初始化

 
 
//Edited by mythou
//http://www.cnblogs.com/mythou/
    //设置主界面画面
        View v_main = LayoutInflater.from(this).inflate(R.layout.main, null);
        mMenu.setContent(v_main);
        //SlidingMenu的view视图
        View sidebar = LayoutInflater.from(this).inflate(R.layout.sidebar, null);
        final ListView listView = (ListView)sidebar.findViewById(android.R.id.list);
        listView.setFooterDividersEnabled(true);
        mSidebarAdapter = new SidebarAdapter();
        listView.setAdapter(mSidebarAdapter);
        mMenu.setMenu(sidebar);
        //底下的信息条
        mInfoLayout = v_main.findViewById(R.id.info_layout);
        mInfoProgress = (ProgressBar) v_main.findViewById(R.id.info_progress);
        mInfoText = (TextView) v_main.findViewById(R.id.info_text);
        //ActionBar初始化
        prepareActionBar();

  界面初始化工作主要分为下面几个部分,可以对照我上面给出的效果图来分析。

  • 设置主Activity的Layout配置
  • SlidingMenu初始化
  • 底下信息条初始化
  • Actionbar初始化

  SlidingMenu的使用,我在另一篇(Android 开发自己的网络收音机2——电台列表(SlidingMenu侧滑栏))里面有详细使用介绍,这里不多说。Activity设置View这个也没什么好说。底下信息条,主要就是一个进度条,主要是搜索文件和生成视频缩略图的时候,给用户提示。本质上是ProgressBar和TextView的组合。最后Actionbar是使用了一个开源项目——ActionBarSherlock,在4.0的系统里面使用这个开源项目,会直接使用系统的ActionBar,所以跟我们使用系统的Actionbar差别不大,后面我们专门写一篇文章说明如何修改Actionbar。

 

5、主Activity布局

//Edited by mythou
//http://www.cnblogs.com/mythou/
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <!-- 这里的FrameLayout负责显示切换的Fragment,是整个程序界面的主要显示模块-->
    <FrameLayout 
        android:id="@+id/fragment_placeholder"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="0dip" />
  
  <!--  下面缩略图生成进度-->  
    <RelativeLayout
        android:id="@+id/info_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone">
        <ProgressBar
            android:id="@+id/info_progress"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:progressDrawable="@drawable/progress"/>
        <TextView
            android:id="@+id/info_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dip"
            android:layout_marginRight="5dip"
            android:singleLine="true"
            android:textColor="#FFFFFFFF"
            android:shadowColor="#CC000000"
            android:shadowRadius="1.5"
            android:shadowDx="1"
            android:shadowDy="1"/>
    </RelativeLayout>
  
   <!-- 音乐后台播放的小的控制台-->
    <FrameLayout
        android:id="@+id/audio_mini_player"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"/>
</LinearLayout>

  最后说说主Activity的布局,这个主Activity布局很简单,上一篇文章我也说过,VLC里面大部分界面都是用Fragment作为显示模块,所以使用的Activity并不多,这里负责切换Fragment显示的Layout是一个FrameLayout,在切换不同的Fragment的时候,都是依靠这个Layout来显示。

  另外就是一个由ProgressBar和TextView组成的信息条,显示缩略图生成的进度。以及下面一个小控件显示,主要是当音乐后台播放的时候,切换到非音乐播放界面,会在底下显示一个音乐播放的控制台。也是使用一个FrameLayout实现。

 

系列文章

Linux 下编译Android-VLC开源播放器详解(附源码下载)

Android VLC播放器二次开发1——程序结构分析

 

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3236071.html 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android VLC播放器二次开发2——CPU类型检查+界面初始化 的相关文章

  • Whatsapp 在 Android 中共享音频文件时正在剪切音频文件

    我在共享格式不是 mp3 的音频文件时遇到问题 文件被共享 但长度较短 例如 如果文件有 10 秒 则仅共享 5 秒 如果我使用 mp3 格式 它会完全共享 但其他格式会出现问题 注意 该文件在其他应用程序 如Messenger 中共享没有
  • 如何使用 Android 版 Facebook 同步的联系人图片

    我的手机上安装了 Android 版 Facebook 它会自动将联系人列表中人员的 FB 个人资料图片同步到我的手机 我想在我访问的应用程序中使用这些图片ContactsContract PhoneLookup 我真的需要 Faceboo
  • Android 构建 gradle 在特定设备上失败

    我面临一个奇怪的问题 当我编译我的应用程序以在 Android 7 0 的设备上运行它时 它可以工作 但是当我尝试为 Android 4 2 1 的设备进行编译时 它会失败并出现以下错误 错误 任务 app transformClasses
  • 服务在后台运行?

    我正在构建的应用程序的功能之一是记录功能 我通过在服务中启动 MediaRecorder 对象来实现此目的 Intent intent new Intent v getContext RecordService class Messenge
  • Android Studio磁盘空间不足如何解决?

    我随机收到此错误 并且不确定为什么 Android Studio 的磁盘空间变低 Android Studio 系统目录分区磁盘空间不足 Update 此应用程序安装在运行 10 10 1 的 Mac 上 具有 251GB 内部存储和占用
  • 从Asynctask返回结果

    如果我的 Android 应用程序中有这个后台工作文件 并且它从我的数据库获取数据 我如何将字符串 结果 传递给另一个类 后台工作人员连接到我的服务器 然后使用 php 连接到数据库 public class BackgroundWorke
  • 如何知道点击的widget id?

    我已经实施了一个widget与ImageButton and a TextView That ImageButton启动一个activity当它被点击时 这activity使用用户在活动上写入的内容更新小部件文本EditText 现在的问题
  • 如何从debug.keystore文件获取MD5?

    我使用一些命令来获取 MD5 私钥debug keystore文件 但实际上我得到的是 SHA1 私钥而不是 MD5 我不知道如何获得MD5 这是我使用的命令 keytool list alias androiddebugkey keyst
  • 来自外部 XML 的 Android 本地化

    是否可以使用从服务接收到的 XML 在运行时翻译 Android 应用程序 如果可能的话 请有人指出我正确的方向 谢谢 Warning 我读到的所有内容都表明 让您的应用程序更改语言不是一个好主意 因为 Android 框架不支持它 并且可
  • 我可以使用“导入 com.facebook.FacebookSdk;”使用 Facebook SDK 3.23.1?

    在我的 app build gradle 文件中 我有compile com facebook android facebook android sdk 3 23 1 在我的 BaseActivity java 文件 其中有 public
  • 对基本适配器类及其功能的疑问

    我正在尝试自定义列表视图 我使用数组列表添加对象列表 并将其发送到扩展基本适配器的类 当我扩展基本适配器类时 它实现了一些方法 例如 getView 等 在 getView 中 我将其发送到将名称 数据 分配给 XML 格式的自定义菜单的类
  • 在Android的activity中调用onResume

    在活动的过程中通过调用 this OnResume 强制 onResume 事件可以吗 或者我应该实现另一个由 OnResume 和第一个成员调用的过程 实现在您的重写中调用的另一个过程onResume 后者不打算由您调用 它是一种方便的方
  • 如果联系人与电话通讯录中的应用程序关联,则显示应用程序图标

    我正在尝试显示与该应用程序关联的电话号码的应用程序图标 我试着跟随this http www c99 org 2010 01 23 writing an android sync provider part 1 链接但是太难了 有没有任何库
  • EditText 的高度不会扩展到其父级的高度

    我在滚动视图中放置了编辑文本 高度 match parent并期望它的高度等于滚动视图 但事实并非如此 它的高度就像wrap content这意味着如果 EditText 中没有文本 我必须将光标指向要弹出的软键盘的第一 行 我想要的是我可
  • 如何使用asynctask显示倒计时的进度条?

    在我的应用程序中 我希望用户按下按钮 然后等待 5 分钟 我知道这听起来很糟糕 但就这样吧 5 分钟等待期间的剩余时间应显示在进度条中 我使用带有文本视图的 CountDownTimer 来倒计时 但我的老板想要看起来更好的东西 这就是进度
  • 在 TextView onTextChanged 上设置文本

    我有一个定义为类属性的文本视图 以便我可以在整个类中访问它 在 onCreate 方法中我执行以下操作 chars TextView findViewById R id chars chars setText 300 之后 public v
  • 在Android中提取视频帧

    我想知道是否可以从 Android 中正在运行的视频中提取帧 我需要定期提取帧并将其发送以进行进一步处理 有人能为我找到答案吗 Thanks Abhi 您可以使用媒体元数据检索器 http developer android com ref
  • 如何用 XML 制作双渐变(类似 iphone)

    如何使用 XML 制作这种可绘制渐变 我可以做一个从颜色 A 到颜色 B 的简单渐变 但我不知道如何在同一个可绘制对象中组合两个渐变 我终于找到了一个带有图层列表的解决方案 这对我来说已经足够好了
  • RecyclerView元素更新+异步网络调用

    我有一个按预期工作的回收视图 我的布局中有一个按钮可以填充列表 该按钮应该进行异步调用 根据结果 我更改按钮的外观 这一切都发生得很好 但是 当我单击按钮并快速向下滚动列表时 异步调用的结果会更新新视图的按钮 代替旧视图的视图 我该如何处理
  • Android 中带有无尽列表视图滚动的 AsyncTask

    我正在创建一个应用程序 其中我需要有无限的滚动列表视图 我不想在我的应用程序中使用任何库 我在网上看到了一些有助于实现此类列表视图的示例 但我的疑问是 当我的数据来自服务器并在异步任务中进行解析时 如何才能拥有无尽的列表视图 如何从滚动异步

随机推荐

  • Gradle SNAPSHOT 版本更新

    转自 https www cnblogs com scoftlin p 9809623 html 在引用Maven 库上的aar 时经常会出现我们更新依赖的库时 Studio 并不能及时将最新的依赖库拉下来 这个因为gradle为了加快构建
  • [机器学习与scikit-learn-46]:特征工程-特征选择(降维)-2-常见的特征降维的方法大全

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 123953894 目录 前言 第1章
  • 服务器安装系统如何收费,服务器系统安装费用

    服务器系统安装费用 内容精选 换一换 根据是否支持高级的SCSI命令来划分磁盘模式 分为VBD 虚拟块存储设备 Virtual Block Device 类型和SCSI 小型计算机系统接口 Small Computer System Int
  • 不使用binlog,canal,kafka等,只用java+mybatis拦截器来实现项目中的异步双写主从数据库,代码逻辑全整理

    项目中因为要迁库 所以我要在原项目中接入我的双写逻辑 确保新旧两个库都有数据写入 假如新库写入失败 旧库数据也能写入 这就确保了重要数据不能丢失 一开始考虑的方案是使用数据同步工具 像是canal或是DTS等 但是环境这块卡的比较死 没有其
  • CSS3 opacity 属性设置 div 元素的不透明级别:

    div 本元素的不透明度是 0 5 请注意 文本和背景色都受到不透明级别的影响 div
  • for循环各部分的执行顺序

    最近在考虑for循环第三个参数是 i or i 如果清楚了for循环各部分的执行顺序的话 其实这个问题无关紧要 因为第三个参数的变化是留给第二个判断语句判断的 所以 i or i 的结果都是增一 判断结果一样 for循环的执行顺序是 初始化
  • vue项目中使用echarts做词云图

    效果图 安装依赖 npm install echarts npm i echarts wordcloud 完整代码
  • Android国际化多语言切换

    关于App国际化 之前有讲到国际化资源 字符换 布局相关 想要了解的猛戳用力抱一下APP国际化 借着本次重构多语言想跟大家聊一下多语言切换 多语言切换对于一款国际化App来讲是重中之重 并非难事 但是若要做好也是一件不容易的事情 问题 An
  • react 中的计算属性 useMemo

    介绍 本篇文章主要是讲解以下 useMemo的正确用法 你们没有看错 useMemo的出现使得react也有了 计算属性 为什么要使用计算属性 其实主要优势就是性能好 通过下面例子可以看出 比较计算属性与普通函数 使用函数完成计算功能 im
  • MySQL安装详细教程!!!

    安装之前 先卸载你之前安装过的数据库程序 否则会造成端口号占用的情况 1 首先下载MySQL MySQL Download MySQL Community Server 下载路径 2 下载版本不一样 安装方法略有不同 版本5的安装基本一致
  • 手欠,给DELL R720加硬盘

    公司有一台比较旧的dell R720服务器 只上了一块15K 300G的硬盘 阵列卡H310M 让采购买了一块4T sata硬盘 因为原来系统上有重要数据 一直没敢动 昨天晚上一狠心直接插上了 什么也不用设置 直接进系统提示发现新硬盘 格式
  • springboot默认日志log,控制台不打印mybatis sql执行日志解决办法

    增加配置 logging level com XXX mapper debug
  • 5.模型训练

    参考PyTorch深度学习快速入门教程 绝对通俗易懂 小土堆 P25 33 现有网络模型的使用及修改 官方文档 以VGG16为例 pretrained True时是已经在ImageNet数据集上训练好的 需要先安装scipy库才能使用Ima
  • 官方 gpt3.5, gpt4.0、github copilot chat、gpt3.5 api、gpt4 api 对比

    这是 进击的Coder 的第 848 篇技术分享 作者 刘志军 来源 Python 之禅 阅读本文大概需要 9 分钟 gpt4 的智能程度大于 gpt3 5 毫无争议 但是 OpenAI 提供的 GPT3 5 API 能力是否和官方的 GP
  • 函数覆盖与函数隐藏

    derive cpp 定义控制台应用程序的入口点 include stdafx h include
  • 光敏电阻控制led亮度程序_单片机开发系统学习LED亮度控制原理

    早期控制LED亮度的方法一般是采用模拟电路来调节LED的工作电流来实现 这种方式灵活性较差 很难达到智能控制的效果 本文将介绍如何通过一个普通MCS51单片机来产生PWM信号 达到调节LED的亮度的目的 一 硬件的简单介绍 该实验在 ME3
  • Python包

    视频版教程 Python3零基础7天入门实战视频教程 对于一个需要实际应用的模块而言 往往会具有很多程序单元 包括变量 函数和类等 如果将整个模块的所有内容都定义在同一个Python源文件中 这个文件将会变得非常庞大 显然并不利于模块化开发
  • VScode配置Python开发环境

    一 下载安装 1 VScode的安装包 Visual Studio Code Code Editing Redefined 2 Python的安装包 Download Python Python org 安装细节我之前也写了篇 请见我的py
  • Java开发工程师有必要转型大数据吗?

    大数据涉及到数据的采集 整理 传输 存储 分析到呈现 涉及到很多岗位和不同的人员配置 很多不同的专业人才都可以参与到大数据行业 这其中有大量的Java程序员考虑从事大数据方面的研发 个人认为 Java程序员从事大数据开发还是有一定优势的 不
  • Android VLC播放器二次开发2——CPU类型检查+界面初始化

    上一篇讲了VLC整个程序的模块划分和界面主要使用的技术 今天分析一下VLC程序初始化过程 主要是初始化界面 加载解码库的操作 今天主要分析一下org videolan vlc gui MainActivity类 这个是VLC的整个程序入口