About Android

try to develop an andorid app

Android problem

Android Studio无法启动


在bin目录的idea.properties文件中添加一行disable.android.first.run=true避免首次启动时自动重新下载SDK(在 Android SDK Manager 中是可以更新SDK)


一个古老的项目,用来同步FF和WB挺好用。看起来一年打包一次?命令行执行gradlew bundle最终限制在Could not resolve com.android.support:support-v4:27.1.1。重新升级AS到4.1版本,智能提醒最后还是提示相同的错误。

Failed to resolve: com.android.support:support-v4:27.1.1类似问题提示,在build.gradle文件中添加——

allprojects {
    repositories {

然后AS提示需要升级NDK到NDK (Side by side) 21.0.6113669 (ndk;21.0.6113669),大小1GB左右

Android Gradle plugin 和gradle版本的对应关系

折腾半天,还是恢复原状是work状态- -|| 升级操作后,java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.widget.SwipeRefreshLayout.setColorSchemeResources(int[])' on a null object reference 因为对于的support版本支持的有问题。

  • 下载使用本地wrapper包
  • 更新key内容weibo console
  • 命令行打包debug版本就够用Build a debug APK执行./gradlew assembleDebug完成编译,产生的文件在module_name-debug.apkproject_name/module_name/build/outputs/apk/目录下(在Andoid Studio仅查看代码)

ps: Mac环境下又重新折腾了一次。23.0.3版本的build-tools在Mac版本下工作不正常,提示错误bad CPU type in executable。重新下载一个高版本24.0的即可。解压后将aaptzipalign可执行文件复制到指定的目录下即可

Android 11 中的存储机制更新从 Android 11 开始,应用无法在外部存储设备上创建自己的应用专用目录。如需访问系统为您的应用提供的目录,请调用 getExternalFilesDirs()。



error default interface methods are only supported starting with android n (–min-api 24)


android {
  compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8


  • 安装包——选择app运行,安装到手机,即可获取到apk
  • 测试包——运行测试代码,即可获取到测试apk


download old adt (Eclipse for android)


Here you can download adt bundles 2014-07-02:

windows 32 bit: https://dl.google.com/android/adt/adt-bundle-windows-x86-20140702.zip

windows 64 bit: https://dl.google.com/android/adt/adt-bundle-windows-x86_64-20140702.zip

MacOS 64 bit: https://dl.google.com/android/adt/adt-bundle-mac-x86_64-20140702.zip

Linux 32 bit: https://dl.google.com/android/adt/adt-bundle-linux-x86-20140702.zip

Linux 64 bit: https://dl.google.com/android/adt/adt-bundle-linux-x86_64-20140702.zip

decompile android apk

How to decompile an APK or DEX file on Android platform

  • unzip apk file to get dex file.
  • d2j-dex2jar.bat classes.dex to get
  • use java decompiler to open jar file.

Decompile Android .apk

use apktool d android.apk to unzip file.

adb forward

adb forward tcp:6100 localabstract:minicap //PC上所有6100端口通信数据将被重定向到手机端minicap的server上 adb forward tcp:6100 tcp:7100 // PC上所有6100端口通信数据将被重定向到手机端7100端口server上 adb forward tcp:6100 local:logd // PC上所有6100端口通信数据将被重定向到手机端UNIX类型socket上

android-studio as desktop entry

How to add Android Studio to the launcher?

Configure -> Create Desktop Entry


[Desktop Entry]
Name=Android Studio
Exec="/home/username/Programs/AndroidStudio/bin/studio.sh" %f

Graphics Buffer

Android’s Graphics Buffer Management System (Part II: BufferQueue)

logcat -v time “*:I” 顺序


使用 logcat “*:I” -v time 在低于5.0版本的设备上无法获取到时间戳。

adb no permissions

Android Debug Bridge (adb) device - no permissions

sudo ./adb kill-server
sudo ./adb start-server
adb devices

# or adn new rule https://stackoverflow.com/a/19291975/1087122
Bus 002 Device 002: ID 8087:8000 Intel Corp. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:8008 Intel Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 009: ID 18d1:4ee7 Google Inc. 

# Create a file /etc/udev/rules.d/99-adb.rules containing the following line:
ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="4ee7", ENV{ID_GPHOTO2}="1", ENV{GPHOTO2_DRIVER}="proprietary", ENV{ID_MEDIA_PLAYER}="1", MODE="0666", GROUP="plugdev"

#Restart udev
$ sudo udevadm control --reload-rules
$ sudo service udev restart

or just change connection mode from charge to PPP(Picture Transfer Protocol). check here

app_process command

app_process command in Android

am start -n yourpackagename/.activityname “am” is just a shell script and what stays in the base of the am script is our app_process binary:

root@android:/ # cat /system/bin/am
cat /system/bin/am
# Script to start "am" on the device, which has a very rudimentary
# shell.
export CLASSPATH=$base/framework/am.jar
exec app_process $base/bin com.android.commands.am.Am "$@"
root@android:/ #

Secure Window

//to forbid screen shot.  W/SurfaceFlinger: FB is protected: PERMISSION_DENIED
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);


注册广播,监听home键 Android Back Home键监听 Detect home button press in android

Adding JAR files to your testing classpath

Adding JAR files to your testing classpath package jar files under testlibs folder.

dependencies {
    testCompile fileTree(dir: 'testlibs', include: ['*.jar'])

download old ndk

ndk old release

download built-tools directly

to install old version of Android build tools from command line

manually open the XML file that is shown when during android sdk list xml detail

 <!-- Built on: Mon Jun  4 07:14:07 2018. -->
<sdk:checksum type="sha1">cf20720e452b642d5eb59dabe05c0c729b36ec75</sdk:checksum>

update UI from background service

update UI from background service

3 basic implementations:

  • Using LocalBroadcastReceivers
  • Using ResultReceiver
  • Using Handlers

How to update UI in a BroadcastReceiver

Does BroadcastReceiver.onReceive always run in the UI thread?


Using lists in Android wth ListView - Tutorial

adb reverse

Network Calls from Android Device to Laptop over USB via ADB Android’s “adb reverse” command is available in Lollipop and higher versions of Android (Platform 21+)

cannot run app on Android 4.4 device The documentation provided is for Android 5.0 and above as adb reverse works only from Android 5.0 and above.

debug on device

debug on device

You must use a build variant that includes debuggable true in the build configuration.

android {
    buildTypes {
        customDebugType {
            debuggable true

Waiting For Debugger

Android Studio stuck at “Waiting For Debugger” forever

menu -> Run -> Attach debugger to Android process




dump应用的权限信息通常可以看到 provides-component:'device-admin'

Android ADB

commond line adb doc for cn

how does adb shell getprop and setprop work

Android system properties are being managed by special property_service. The /system/build.prop is just one out of 4-6 (depending on the version) read-only files containing the default values that property_service uses to populate its internal in-memory database with during start-up. So changes to the files during run time would not propagate until after reboot.

The setprop and getprop commands are used to access the data in that database. Unless the property name starts with persist. - then the value gets stored in /data/property folder.

adb overview and services


A client, which sends commands. The client runs on your development machine. You can invoke a client from a command-line terminal by issuing an adb command. A daemon (adbd), which runs commands on a device. The daemon runs as a background process on each device. A server, which manages communication between the client and the daemon. The server runs as a background process on your development machine.

The source code for all 3 parts of ADB is in the same system/core/adb folder. overview services

adb devices

Where is the ADB server code that handles the “devices” command?

source code for this question

it’s in adb.cpp

gradle dependencies

dependencies types

// Dependency on a local library module
implementation project(":mylibrary")

// Dependency on local binaries
implementation fileTree(dir: 'libs', include: ['*.jar'])

// Dependency on a remote binary
implementation 'com.example.android:app-magic:12.3'

dependency configurations



proguard not work for test app, see this

build apk without test app

you need to go to Build > Build APK(s) to have a non testable release apk that you can submit to the store.

Unable to add window. Permission denied for this window type

Unable to add window. Permission denied for this window type

If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen.

private static final int OVERLAY_PERMISSION_REQ_CODE = 100;
    private Context context;

    protected void onCreate(Bundle savedInstanceState) {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        context = MainActivity.this;

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            public void onClick(View view) {
                //add the service here
                //make the button gone

                if ((Build.VERSION.SDK_INT >= 23)) {
                    if (!Settings.canDrawOverlays(context)) {
                        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                Uri.parse("package:" + getPackageName()));
                        startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
                    } else if (Settings.canDrawOverlays(context)) {
                        startService(new Intent(context, FloatingCircle.class));
                    startService(new Intent(context, FloatingCircle.class));



    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            startService(new Intent(context, FloatingCircle.class));


Unable to instantiate service

You service needs to have a public no-args constructor. Otherwize, Android will not be able to instantiate it. Unable to instantiate service


Android Studio

“cannot resolve symbol R” in Android Studio

“cannot resolve symbol R” in Android Studio

  1. 确保xml文件没有错误内容;
  2. clean project and build and sync
  • Build -> Clean Project
  • File -> Sync Project with Gradle Files (tools bar with circle icon)

Cannot resolve symbol ‘xxx’

AS特有的诡异问题。现象为:gradle build成功,但编辑器里总是提示Cannot resolve symbol ‘xxx’。

  1. invalidate cache and restart 不一定好使;
  2. clean and rebuild project也无效
  3. 这时候,先需要将dependencies里对应的内容先注销(sync一次),再重新打开注释的dependencies内容,再sync一次

insufficient permissions for device

need to restart adb server. adb kill-server ; adb start-server

adb shell 出现 insufficient permissions for device

about icon

Android drawable的细节

# icon size 
密度  建议尺寸
mipmap-mdpi 48 * 48
mipmap-hdpi 72 * 72
mipmap-xhdpi  96 * 96
mipmap-xxhdpi 144 * 144
mipmap-xxxhdpi  192 * 192

# about dpi
float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;

dpi范围 密度
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

Android APK




# need java JDK environment
# keytool --help
# keytool -genkey -help
 ~ keytool -genkey -alias gebitang -keyalg RSA -validity 20000 -keystore ./gebitang.keystore
Enter keystore password:
Re-enter new password:
What is your first and last name?
  [Unknown]:  JOECHINLI
What is the name of your organizational unit?
  [Unknown]:  gebitang
What is the name of your organization?
  [Unknown]:  geb
What is the name of your City or Locality?
  [Unknown]:  Beijing
What is the name of your State or Province?
  [Unknown]:  Beijing
What is the two-letter country code for this unit?
  [Unknown]:  cn
Is CN=JOECHINLEE, OU=gebitang, O=geb, L=Beijing, ST=Beijing, C=cn correct?
What is your first and last name?
What is the name of your organizational unit?
What is the name of your organization?
What is the name of your City or Locality?
What is the name of your State or Province?
What is the two-letter country code for this unit?
Is CN=JOECHINLEE, OU=gebitang, O=geb, L=Beijing, ST=Beijing, C=cn correct?
  [no]:  yes

Enter key password for <gebitang.keystore>
  (RETURN if same as keystore password):

dumpsys command

dumpsys command

# list?
adb shell dumpsys -l
Currently running services:

# list
adb shell service list

Found 111 services:
0 ims: [com.android.ims.internal.IImsService]
1 sip: [android.net.sip.ISipService]
2 com.qualcomm.location.izat.IzatService: [com.qualcomm.location.izat.IIzatService]
3 carrier_config: [com.android.internal.telephony.ICarrierConfigLoader]
110 android.security.keystore: [android.security.IKeystoreService]


Android Studio的两种模式及签名配置

  • 使用release版本 by Build Variants


实际使用中发现静态变量赋值后再次使用时依然是原始默认值。建议使用Shared Preferences或者统一定义 Application中。



# AndroidManifest.xml
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />

public class SmsBroadcastReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        sendSms(context, intent);

# actual method
void sendSms(Context context, Intent intent) {
  if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
      String smsSender = "";
      StringBuilder sb = new StringBuilder();
          for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
              smsSender = smsMessage.getDisplayOriginatingAddress();
      } else {
          Bundle smsBundle = intent.getExtras();
          if (smsBundle != null) {
              Object[] pdus = (Object[]) smsBundle.get("pdus");
              if (pdus == null) {
                  // Display some error to the user
                  Log.e(Utils.tag, "SmsBundle had no pdus key");
              SmsMessage[] messages = new SmsMessage[pdus.length];
              for (int i = 0; i < messages.length; i++) {
                  messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
              smsSender = messages[0].getOriginatingAddress();
      SharedPreferences settings = context.getSharedPreferences(Const.SAVE_DATE, 0);
      String phone = settings.getString(Const.phoneNum, SmsHelper.getPhoneNumber());
      String url = settings.getString(Const.smsUrl, SmsHelper.getReceiveSmsUrl());
      //Log.i(Utils.tag,  url+ " now phone number: " + phone);
      HttpClientUtil.uploadSmsInBackground(smsSender, sb.toString(), phone, url);

Android Surface System

Bn: BinderNative Bp: BinderProxy Java上层利用binder调用C++层的bn端,而后C++的bn端再将请求返回给上层

BpBinder binder的proxy端 BBinder 与BpBinder对应的端

 * Base class and low-level protocol for a remotable object.
 * You can derive from this class to create an object for which other
 * processes can hold references to it.  Communication between processes
 * (method calls, property get and set) is down through a low-level
 * protocol implemented on top of the transact() API.
class IBinder : public virtual RefBase

 * This class defines the Binder IPC interface for accessing various
 * SurfaceFlinger features.
class ISurfaceComposer: public IInterface

 * This class defines the Binder IPC interface for the producer side of
 * a queue of graphics buffers.  It's used to send graphics data from one
 * component to another.  For example, a class that decodes video for
 * playback might use this to provide frames.  This is typically done
 * indirectly, through Surface.
 * The underlying mechanism is a BufferQueue, which implements
 * BnGraphicBufferProducer.  In normal operation, the producer calls
 * dequeueBuffer() to get an empty buffer, fills it with data, then
 * calls queueBuffer() to make it available to the consumer.
 * This class was previously called ISurfaceTexture.
class IGraphicBufferProducer : public IInterface

 * CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU
 * access to the underlying gralloc buffers provided by BufferQueue. Multiple
 * buffers may be acquired by it at once, to be used concurrently by the
 * CpuConsumer owner. Sets gralloc usage flags to be software-read-only.
 * This queue is synchronous by default.

class CpuConsumer : public ConsumerBase

// ConsumerBase is a base class for BufferQueue consumer end-points. It
// handles common tasks like management of the connection to the BufferQueue
// and the buffer pool.
class ConsumerBase : public virtual RefBase,
        protected BufferQueue::ConsumerListener 

 * This class defines the Binder IPC interface for the producer side of
 * a queue of graphics buffers.  It's used to send graphics data from one
 * component to another.  For example, a class that decodes video for
 * playback might use this to provide frames.  This is typically done
 * indirectly, through Surface.
 * The underlying mechanism is a BufferQueue, which implements
 * BnGraphicBufferProducer.  In normal operation, the producer calls
 * dequeueBuffer() to get an empty buffer, fills it with data, then
 * calls queueBuffer() to make it available to the consumer.
 * This class was previously called ISurfaceTexture.
class IGraphicBufferProducer : public IInterface

class BufferQueue : public BnGraphicBufferProducer




  1. getCpuConsumer():新建一个consumer,
  2. 调用SurfaceFlinger端的captureScreen方法生成截图
  3. 使用1中的consumer消费2中的截图,保存到指针mBuffer指向的内存中


  1. 根据传递的参数设置截图信息,实际宽高、截图宽高、rotation;设置listener,传递给2中重新封装的FrameProxy

  2. 应用1中的配置 createVirtualDisplay(): createDisplay返回一个远程对象用来显示DisplayToken == SurfaceFlinger? 从Cpuconsumer中获取BufferQueue: BnGraphicBufferProducer,设置(图片)大小和(图片)格式。 重新包装了一个listener—— class FrameProxy: public android::ConsumerBase::FrameAvailableListener consumer设置setFrameAvailableListener。class CpuConsumer : public ConsumerBase

    设置消费所需要用到的各个信息?最终获取到一个DisplayState 所需的内容 android::SurfaceComposerClient::setDisplaySurface(mVirtualDisplay, mBufferQueue); android::SurfaceComposerClient::setDisplayProjection(mVirtualDisplay, android::DISPLAY_ORIENTATION_0, layerStackRect, visibleRect); android::SurfaceComposerClient::setDisplayLayerStack(mVirtualDisplay, 0); // default stack

通用逻辑: 使用surfaceComposerClient调用SurfaceFlinger中的具体实现

/frameworks/native/include/private/gui/LayerState.h struct DisplayState

BufferQueue这个类是由应用程序在客户端通过和服务端的Client交互,提交消息给SurfaceFlinger处理时创建的Layer对象时在SurfaceTextureLayer类构造中创建的: BufferQueue中有一个成员变量BufferSlot mSlots[NUM_BUFFER_SLOTS];即一个BufferQueue实际上最大可以有32个Buffer,即一个应用程序申请的Surface在SF端的Layer可以有32个图像缓存区。而这32个图形缓存区都有上面的mSlots维护着,每个Buffer有以下几种可变的状态,由BufferState mBufferState维护: 分别是FREE,DEQUEUED,QUEUE,ACQUIRED这4个状态,分别是空闲,出列被填充数据,入列代表有了数据,最终将入列后有了图形数据的缓冲区进行渲染。



Android4.2.2 SurfaceFlinger之图形缓存区申请与分配dequeueBuffer


Graphics architecture


the system service that consumes the currently visible surfaces and composites them onto the display using information provided by the Window Manager. SurfaceFlinger is the only service that can modify the content of the display. SurfaceFlinger uses OpenGL and the Hardware Composer to compose a group of surfaces.


is an Android system service, responsible for compositing all the application and system surfaces into a single buffer that is finally to be displayed by display controller.

Let’s zoom in above statement.

SurfaceFlinger is a system wide service but it is not directly available to application developer as Sensor or other services can be. Every time you want to update your UI, SurfaceFlinger will kick in. This explains why SurfaceFlinger is a battery drainer.

Besides your application surfaces, there are system surfaces, including status bar, navigation bar and, when rotation happens, surfaces created by the system for rotation animation. Most applications have only one active surface - the one of current foreground activity, others have more than one when SurfaceView is used in the view hierarchy or Presentation mode is used.

SurfaceFlinger is responsible for COMPOSITING all those surfaces. A common misunderstanding is that SurfaceFinger is for DRAWING. It is not correct. Drawing is the job of OpenGL. The interesting thing is SurfaceFlinger used openGL for compositing as well.

The composition result will be put in a system buffer, or native window, which is the source for display controller to fetch data from. This is what you see in the screen.



F:\>aidl -IF:\android\sources\08_android-2.2\frameworks\base\core\java\ -IF:\android\sources\08_android-2.2\frameworks\base\graphics\java F:\android\sources\08_android-2.2\frameworks\base\core\java\android\view\IWindowSession.aidl testme.java
F:\>aidl -IF:\android\sources\18_android-4.3_r2.3\frameworks\base\core\java\ -IF:\android\sources\18_android-4.3_r2.3\frameworks\base\graphics\java\ F:\android\sources\18_android-4.3_r2.3\frameworks\base\core\java\android\view\IWindowSession.aidl testme18.java
INPUT required
       aidl --preprocess OUTPUT INPUT...

   -I<DIR>    search path for import statements.
   -d<FILE>   generate dependency file.
   -a         generate dependency file next to the output file with the name based on the input file.
   -p<FILE>   file created by --preprocess to import.
   -o<FOLDER> base output folder for generated files.
   -b         fail when trying to compile a parcelable.

   An aidl interface file.

   The generated interface files.
   If omitted and the -o option is not used, the input filename is used, with the .aidl extension changed to a .java extension.
   If the -o option is used, the generated files will be placed in the base output folder, under their package folder

Configuration with name ‘debugAndroidTestCompile’ not found.

caused by protobuf

该问题是gradle 版本和 protobuf 依赖版本不匹配导致的,所以用新的 protobuf 就可以了

    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'

comments powered by Disqus