Fork me on GitHub

使用Gradle生成一个App的不同版本,且可以同时安装在一个手机上 2014-08-03

背景

开发一个App一般会生成内测版和正式版,甚至还会有不同渠道的版本,不同版本的配置可能会不一样,比如内测版会需要记录完整的日志。

Android手机对于同样的Application Id的App只能安装一个版本,如果我们需要同时安装内测版和正式版,就必须修改其中一个版本的Application Id。

解决方案

Gradle支持buildTypes和productFlavors两种定制方法,这里只介绍通过buildType的解决方案。通过productFlavors则可有效解决渠道包,arm,x86等分平台以及付费版和广告版的打包问题。

修改debug版的包名

配置如下:

android {
    buildTypes {
        release {
            ...
        }

        debug {
            applicationIdSuffix '.debug'
            ...
        }
    }
}

安装第三方App到电视盒子 2014-07-26

安装第三方App方法1

  1. 准备一个U盘,注意用FAT格式(Windows能读写就OK)
  2. 将需要安装的App下载到U盘,文件后缀名必须是.apk
  3. 将U盘插入电视盒子,然后通过盒子自身带的文件管理App安装:如Magic Box:应用--> 本地播放,进入后选中U盘上的.apk文件即可安装

安装第三方App方法2

  1. 如果盒子不带USB盘,还可以用adb远程安装
  2. adb connect <your_magic_box_ip>
  3. adb install <you_app_to_install>.apk

直播和回放App

  1. 在电脑上用浏览器下载:http://app.shafa.com/shafa.apk 到U盘
  2. 按方法1安装好后,在“应用“中找到“沙发管家”
  3. 启动“沙发管家”,安装直播App:如“龙龙直播”,也有支持回放的App,如“电视猫视频”等。

Gradle的Properties 2014-07-23

问题背景

团队一起在开发一个Android项目,工程师有的使用Eclipse,有个使用Intellij IDEA,有的使用Android Studio。每个人安装的Android SDK build-tools可能都不一样,有的是19.0.3,有的是19.1.0,不同版本的build-tools对Gradle Plugin也有相应的要求,如19.0.3对应的是com.android.tools.build:gradle:0.10.+,19.1.0对应的是com.android.tools.build:gradle:0.12.+,下面是一个典型的build.gradle配置文件。

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.10.+'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion 19
    buildToolsVersion 19.0.3

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
    }
}

Android异步编程 2014-06-29

Android的线程和内存模型

Android操作系统在boot后,会启动一个Zygote(受精卵)进程,Zygote进程负责创建大部分应用程序进程。Zygote进程启动加载核心程序库和数据结构到内存后会创建一个Dalvik虚拟机(DVM)进程--SystemServer,此进程会包含大部分的系统服务(包括管理Activity的服务ActivityManagerService),SystemServer初始化后,Zygote进程会侦听本地的socket端口, 等待进一步的指令。当新的app被启动时,Zygote会为这个app创建一个DVM—-直接fork出一个子进程,这种架构的好处是同时启动多个App时,多个App进程可以访问共享内存。

Android App的进程也是一个DVM,内部有许多线程在执行,比如,主UI线程(Main Thread),垃圾回收线程等。其中主UI线程负责执行我们写的应用代码。对于只做很少的I/O操作或耗时操作的App,单一线程开发模式问题不大,但是如果有大量IO或者CPU计算的任务,我们就必须在其他线程内完成了。

因为主UI线程需要根据硬件刷新率[^3]同步用户界面的重绘。手机应用体验流畅要求界面帧率[^3]达到每秒60,也就是说每16.67毫秒就需要重绘一帧,这意味着如果我们在主线程上执行的任务超过16毫秒,就会出现丢帧现象,也就是界面会开始变卡。。。

Android异步执行任务的方法有以下几种:

AsyncTask

AsyncTask是最常用的异步方法,功能结构设计的也很丰富,给使用者足够的控制,使用上主要是将异步执行的任务放在下面方法里。

提高Android开发效率的小贴士 2014-02-10

查看日志 adb logcat

下面命令将只显示错误日志,和所有Tag=mytag的调试日志,-C 会用不同颜色区分不同级别的日志,但只有Android 4.3以后才支持。

adb logcat [-C] *:E <mytag>:D

远程调试 adb over TCP

首先在手机或Pad上执行以下命令(要求root)

su
setprop service.adb.tcp.port 5555
stop adbd
start adbd

再执行下面命令则可以看到手机的网络地址

拷贝Android应用的数据 2013-11-27

有root权限

adb shell su -c cat /data/data/app.package.name/databases/application.sqlite | sed 's/\r$//' > application.sqlite

应用可调试的话

adb shell
run-as app.package.name \
cp /data/data/package.name/databases/application.sqlite /sdcard/
exit
adb pull /sdcard/application.sqlite ~/

使用备份方法

adb backup -f ~/data.ab -noapk app.package.name
dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -

在树莓派上使用Phantomjs自动登录微博 2013-07-21

使用过新浪开放平台的朋友都知道用户对小应用(用户数较少的)的授权Token很容易过期,自动续期要求授权过的用户在过期前重新打开授权页。如果你想实现一个自动备份自己微博的App,就不得每天(周)自己去访问授权页(想死的心都有了吧?)。这里介绍一种通过脚本自动登录微博获取最新oAuth token的方法(需要微博登录名和密码),合适自己玩。将脚本部署在树莓派上后,我再也不用每周都去登录一次授权页了,只是收到报警消息后(经常是帐号被冻结了)需要手动处理一下。

Phantomjs

Phantomjs 是一个开源的,没有界面可运行在命令行,跨平台,基于WebKit的全功能浏览器,可以用来做网站自动化测试。从源代码编译比较费时间,可以直接下载二进制版本,树莓派的版本在这里可下载。Phantomjs下载好了后就一个可执行文件,依赖非常少,我很喜欢这种方式。

代码

以下代码使用提供的微博用户名和密码登录,获得Token后还会打开微博首页看帐号是否被冻结了。

var page = require('webpage').create(),
    system = require('system'),
    fs = require('fs'),
    address;

var weibo_userid = system.args[1]
var weibo_passwd = system.args[2]

var startUrl = "https://api.weibo.com/oauth2/authorize?client_id=<your_app_key>&redirect_uri=<your_return_url>/&response_type=token";

var verify_weibo_freeze = false;

page.onResourceReceived = function (res,network) {
    if (res.stage == "end") {
        // console.log("\t<-" + res.url);
        if (res.url.indexOf("authorize?client_id")>0) {
            startUrl = res.url
        } 
        if (res.url.indexOf("?access_token")>0) {
            var pos1 = res.url.indexOf("access_token=")
            var pos2 = res.url.indexOf("&")
            var access_token = res.url.substring(pos1+"access_token=".length, pos2)
            console.log(weibo_userid + " login OK, access_token is: " + access_token)
            verify_weibo_freeze = true
        }
        if (verify_weibo_freeze && res.url != "http://weibo.com/" && res.url.indexOf("http://weibo.com/")>-1) {
            var pos1 = res.url.indexOf("/",8)
            var pos2 = res.url.indexOf("?")
            var weibo_name = res.url.substring(pos1+1,pos2)
            console.log(weibo_name+" status verified OK")
            phantom.exit();
        }
    }
};

page.onLoadFinished = function() {
    if (verify_weibo_freeze) {
        page.open("http://weibo.com/", function() {
            phantom.exit();
        })
    }
};

page.onConsoleMessage = function(msg) {
    console.log(msg);
};

page.open(startUrl, function(status) {
    if ( status === "success" ) {
        page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
            var offset = page.evaluate(function(a,b) {
                $("#userId").val(a)
                $("#passwd").val(b)
                if ($('.WB_btn_login').hasClass("formbtn_01")) {
                    // console.log("Found button!")
                    return $('.WB_btn_login').offset()
                }
                return undefined
            }, weibo_userid, weibo_passwd);
            page.sendEvent('click', offset.left + 1, offset.top + 1);
        });
    }
})

使用夏普GP2Y1010AU0F灰尘传感器检测空气质量 2013-07-21

夏普GP2Y1010AU0F灰尘传感器价格较便宜,能检测出室内空气中的灰尘和烟尘含量。另外还有韩国SYHITECH生产的DSM501A粉尘传感器也有类似功能。

检测原理

其原理如下图,传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。

电路图

因为数据是通过pin 5的电压模拟信号输出的,而树莓派的引脚不支持模拟信号直接读取(需要增加数模转换芯片),所以先用Arduino来实验。

替换树莓派的U盘 2013-07-11

除了SD卡上的存储,树莓派还可以使用U盘来做存储,有时候我们可能需要替换已有的U盘为更大容量的。在Mac上可以采用下面的方法:

  1. 备份已有的U盘,把U盘从树莓派上拔下来插在Mac上,找出U盘对应的盘符(下例为/dev/disk2

    20:51:19 hugozhu-mac-mini ~ $ diskutil list
    /dev/disk0
       #:                       TYPE NAME                    SIZE       IDENTIFIER
       0:      GUID_partition_scheme                        *500.1 GB   disk0
       1:                        EFI                         209.7 MB   disk0s1
       2:                  Apple_HFS Macintosh HD            499.2 GB   disk0s2
       3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
    /dev/disk2
       #:                       TYPE NAME                    SIZE       IDENTIFIER
       0:     FDisk_partition_scheme                        *2.1 GB     disk2
    

    使用 dd 命令把U盘拷贝到raspberrypi.img

在Mac上使用Sublime 3写Go代码 2013-07-11

Sublime 是一个相当好用的文本编辑器,界面简洁,功能强大。最近Sublime 3 Beta 出来了, 体验了一下,发现启动速度比之前快了很多。

下载安装

下载地址: http://www.sublimetext.com/3

安装Package Control

Sublime 支持插件来丰富其功能,package control 本身也是一个插件,可以用来管理其他插件,所以我们要先安装Package Control,Sublime 3需要安装Pacakge Control Alpha.

cd "Library/Application Support/Sublime Text 3"
cd Packages/
git clone https://github.com/wbond/sublime_package_control.git "Package Control"
cd "Package Control"
git checkout python3