
android
RichardChiang
小步快跑,逐步迭代
展开
-
内存泄漏-内部类持有外部类引用
1.内部类持有外部类引用我们在处理Android内存泄漏的时候,经常会遇到一些是由于内部类持有外部类引用而引发的。严格来说是非static的内部类的非static对象或匿名内部类的非static对象持有了当前所在外部类的引用造成的。下面我们用一个例子来进行说明public class LeakTestActivity extends BaseActivity { private But...原创 2019-11-25 00:28:45 · 5445 阅读 · 5 评论 -
Android Activity的生命周期
1. Android Activity的生命周期在一个activity的生命周期中,系统会像金字塔模型一样去调用一系列的生命周期回调函数。Activity生命周期的每一个阶段就像金字塔中的台阶。当系统创建了一个新的activity实例,每一个回调函数会向上一阶移动activity状态。处在金字塔顶端意味着当前activity处在前台并处于用户可与其进行交互的状态。 Figure1 activi原创 2016-12-13 16:38:17 · 481 阅读 · 0 评论 -
ButterKnife控件无响应
本文主要说明一些在使用这个框架中的控件无响应的细节:1. AndroidStudio中添加ButterKnifeFile->Settings->Plugin,输入butter搜索,并安装重启AndroidStudio. 安装ButterKnife插件 这时在我们的工程的app下的build.gradle中添加上了下面一段代码:compile 'com.jakewharton:butterkn原创 2016-12-13 16:47:11 · 1960 阅读 · 0 评论 -
AndroidStudio导入项目过慢
当我们使用AndroidStudio(AS)导入项目File->New->Import Project时,常常需要等待很长一段时间,这是因为此时AS一直在根据项目\gradle\wrapper\gradle-wrapper.properties中的配置信息:distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-al原创 2016-12-20 17:37:10 · 1841 阅读 · 0 评论 -
自定义Android资源覆盖rro方案
1. framework层rro资源覆盖方案在\framework\base\core\jni\android_util_AssetManager.cpp中: before:static void android_content_AssetManager_init(JNIEnv* env, jobject clazz, jboolean isSystem){ if (isSystem)原创 2016-12-04 12:26:42 · 2071 阅读 · 2 评论 -
Android运行时资源替换-Runtime Resource Overlay
一、替换第三方应用的资源1.需求提出在Android中当我们需要修改某个应用的一些资源时,例如app中的图片资源、文字资源和颜色等时,最直接的做法就是在应用的代码中修改对应的资源文件。以下就是一个简单的例子: 应用的目录结构 应用运行的效果 现在我们需要修改“这是原生应用的资源”这段文字,最直接的做法就是在应用中修改对应的资源内容:res/values/strings.xml<?xml原创 2016-11-20 11:48:44 · 12122 阅读 · 2 评论 -
Bootchart分析Android6.0开机性能
Bootchart是一个用于Linux启动过程性能分析的开源软件工具,以可视化的方式对GUN/Linux的开机启动过程进行性能分析,包括资源的使用(如CPU,磁盘等),各进程的执行时间信息等。根据分析结果,确定系统启动的性能瓶颈,制定相应的优化策略。由于Android系统是基于Linux的,所以我们可以使用Bootchart来分析开机性能。实际上在Android中已经集成了Bootchart这一开源原创 2017-03-27 22:53:28 · 5474 阅读 · 2 评论 -
LeakCanary检测内存泄漏源码分析
关于LeakCanary的出身和作用这里就不多说了,也不是本文的重点。这些入门知识可以参考如下博客LeakCanary中文使用说明。 LeakCanary检测内存泄漏(主要Activity内存泄漏)主要分为3个部分:监听 监听对象(Activity)的生命周期,并在对应回调接口(onDestroy)中做检测。检测 在监听中的回调接口(一般是一个对象本应该被销毁的地方)里面检测对象是否...原创 2018-07-27 22:50:43 · 237 阅读 · 0 评论 -
FFmpeg系列(一)-Mac环境下使用NDK编译FFmpeg
如果需要做音视频相关的内容,必然绕不开的一个东东就是FFmpeg。它是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。总之FFmpeg是处理音视频非常强大的一个...原创 2019-04-11 11:06:19 · 756 阅读 · 0 评论 -
FFmpeg系列(二)-Android项目引入FFmpeg库播放视频
在系列一中讲述了如何编译FFmpeg的源码,现在就在Android项目中引入我们编译出来的库,并实现播放一个在线视频的功能新建Android工程新建一个支持ndk的Android工程,在AS中新建工程就不再详述了,详细的新建ndk工程,可以参考AndroidStudio中使用JNI/NDK示例 需要注意的一点就是在新建导航中注意勾选Support C++这个选项,这样新建的Android工程就...原创 2019-04-11 16:12:02 · 500 阅读 · 0 评论 -
Android疑难杂症之TimeoutException
1.分析原因在android开发中经常会到一些即使看了堆栈也无法快速定位的问题,因为这些堆栈几乎都是系统代码,并无业务代码,而且发生crash打印的堆栈也不一定是这个地方导致的。例如我们今天要讨论的java.util.concurrent.TimeoutException,我们这里能查询到一个上报的堆栈如下:java.util.concurrent.TimeoutException: and...原创 2019-07-04 00:30:07 · 2028 阅读 · 0 评论 -
Android疑难杂症之Toast引起的BadTokenException
1.现象分析当我们将targetSDK升级到26以上后,发现项目中报告了很多BadTokenException异常,查看堆栈几乎都与Toast有关:通过堆栈查看源码知道Toast是通过内部类TN的handleShow()方法来展示浮窗,而这个方式是可能会抛出WindowManager.BadTokenException异常的,虽然api26之后google对这个异常进行了捕获,使其不至于造成...原创 2019-07-09 21:14:59 · 744 阅读 · 0 评论 -
Layout中的weight
weight 权重的值指的是每个部件所占剩余空间的大小,该值与同级部件所占空间大小有关。例如,我们设置一个View的权重是2,另一个View的权重是1,那么总数就是3,这时第一个View占据2/3的空间,第二个占据1/3的空间。对于所有的View默认的权重是0,如果只设置了一个View的权重大于0,则该View将占据除去别的View本身占据的空间的所有剩余空间。例如这里的一个EditText和Bu原创 2016-12-13 16:30:19 · 373 阅读 · 0 评论 -
Android系统Java层访问Native层函数
Android系统中Java层函数需要访问Native层函数的话,需要通过Jni,下面通过一个示例来演示windows环境下,在java中调用C库函数。1、编写java代码。在java层写好类和函数,例如HelloJNI.java:class HelloJNI { // 本地方法声明 native void printHello(); native void printStri原创 2016-10-14 09:57:34 · 1933 阅读 · 0 评论 -
Android中报错 FATAL EXCEPTION MAIN
Android中报错 FATAL EXCEPTION MAIN出现这个问题的原因多半是因为所用到的资源没有找到: 例如: 1、资源引用错误TabSpec spec2 = tabHost.newTabSpec("tab2");spec1.setIndicator("通知公告");spec1.setContent(R.id.tabNotification);tabHost.addTab(s原创 2015-03-14 11:37:22 · 3972 阅读 · 0 评论 -
Socket及时通讯小范例
服务端(测试通过):package org.whu.jay;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Serve原创 2015-04-05 11:31:17 · 726 阅读 · 0 评论 -
Android中广播接收者的注册与释放
Android中常常利用广播机制来在各个组件之间传递消息,例如在Activity和Service之间。 在Activity中注册广播接收者,来接收来自Service的广播:public class LoginReceiver extends BroadcastReceiver { private boolean loginResult = false; @Overr原创 2015-04-06 16:44:20 · 3891 阅读 · 0 评论 -
Android自定义对话框
对话框的布局: linkSetting.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height原创 2015-04-14 17:04:54 · 542 阅读 · 0 评论 -
服务端和Android客户端利用Socket传输JSON数据
JSON是一种组织数据的结构模型(和XML类似),当需要在服务端和Android客户端之间传递大量字符串数据时,采用JSON往往比较高效。 服务端(核心代码):byte[] jsonByte = polmanListStr.getBytes("GB2312");DataOutputStream output = new DataOutputStream(socket.getOutputStre原创 2015-04-08 22:37:36 · 5976 阅读 · 0 评论 -
Android项目使用Lame库录制.mp3格式音频
在android开发中常常需要使用设备录制音频,但是得到的音频文件格式通常是.ma4或.arm等格式,为了得到具有通用格式的mp3音频文件。这里可以在andoid项目中使用开源库。 从github上下载了一个开源项目,这个android项目中使用了lame这个开源库来录制mp3格式的音频文件。下面通过几个步骤来一步一步移植下载的开源项目到自己的android开源项目中: 1、在eclipse中配原创 2015-05-04 22:24:57 · 2659 阅读 · 0 评论 -
Android开机动画流程
Android系统在启动过程中,最多可以出现三个画面。第一个开机画面是在内核启动的过程中出现,是一个静态的画面;第一个画面是在init进程启动的过程中出现的,也是一个静态的画面;第三个画面是在系统服务启动的过程中出现 ,是一个动态的画面。着三个画面都是在一个被称为帧缓冲区(frame buffer,简称fb)的硬件设备上进行渲染的。本文主要分析第三个启动画面的流程。 在Android层动画的流程图转载 2016-09-13 17:58:28 · 7866 阅读 · 0 评论 -
Android7.0中PopupWindow弹出位置异常问题
我们在Android开发中经常会使用到PopupWindow来显示内容,在Android7.0以前。 // 定义一个PopupWindow变量,并设置宽、高 PopupWindow popupWindow = new PopupWindow(mWidth, mHeight); popupWindow.setFocusable(true); // 在某个控件下原创 2016-10-25 17:49:20 · 9906 阅读 · 5 评论 -
关于adb shell命令后报错error:device not found的一种解决方案
做Android开发连接手机调试时,明明已经打开了开发模式,允许USB调试,连接上手机后仍然无法发现设备,在控制台中输入adb shell后报错error:device not found。网上的做法大致分为: 1、adb kill-server来杀死adb进程,然后再使用adb start-server来开启命令; 2、检测5037(adb.exe默认端口)是否被占用,关闭除adb.exe以外原创 2016-10-19 11:07:28 · 107030 阅读 · 5 评论 -
画笔paint的使用
在android编程中,画图形就一定需要使用画笔:Paint p = new Paint();这里仅仅是构造了画笔对象,但还需要设置画笔的属性,然后设置画笔的属性。在onDraw()函数之外进行设计就会报错:要设置画笔的属性,必须在onDraw()函数当中进行:原创 2015-03-01 11:46:40 · 654 阅读 · 0 评论