Android Activity Launch Mode

Activity的launchMode:singleTop,singleTask与singleInstance

 

相关内容,可以参见官方网址:http://developer.android.com/guide/components/tasks-and-back-stack.html

如图所示,如果ABC三个Activity的launchMode都是standard,那么按照图示顺序调用后,堆栈为ABCBB;
而如果界面ActivityB的launchMode为singleTop,同样的调用关系下,堆栈为ABCB,栈顶的B,被复用了。

singleTop模式,适合于与用户交互时保持信心更新的界面Activity,比如联系人的搜索界面界面等;

singleTop仅作为栈顶Activity时才可能被复用,同一个Activity在系统中,还是会存在多个的现象。
singleTasksingleInstance,在整个系统中,仅会有一个对象存在,以节省内存开销。
如果运行模式不是默认的standard模式,那么,该Activity需要重载onNewIntent的函数。
standard和singleTop,对它的调用,不会引起任务切换;而singleTask和singleInstance,则相反。
换句话说,而singleTask和singleInstance,其Activity的对象,仅可作为任务的根Activity而存在,
而standard和singleTop,其Activity的对象,则可能存在Activity堆栈的任何位置。

如图所示,当B的运行模式为singleTask和singleInstance时,所有对B的调用,
都会跳转到以B为根的任务中进行,而与调用Activity所在的任务,毫无关联。

singleTask和singleInstance唯一的区别是:
singleInstance,其所在的任务中,包含且只包含一个该Activity的对象,不会再有其他的Activity对象;
而singleTask,其任务中,则可能包含多个其他相关的Activity对象。

singleTask和singleInstance适用于消耗内存较多的单实例界面,比如浏览器和音乐播放器等。

摘自《Android开发精要》

开源字体: source-han-sans (思源字体)

source-han-sans (思源字体)

Adobe 与 Google 联合开发的开源字体, 参见《Introducing Source Han Sans: An open source Pan-CJK typeface

http://blog.typekit.com/

下载:

https://github.com/adobe-fonts/source-han-sans/

许可:  1.001及其更早采用 Apache 2.0 license

1.002及其以后采用 SIL Open Font License

 

Google Noto Font:

http://www.google.com/get/noto/

 

https://github.com/googlei18n?query=noto

Build openjdk 7 on ubuntu 10.10

sudo apt-get install git mercurial zip bzip2 unzip tar gawk
sudo apt-get install ccache make gcc g++ ca-certificates ca-certificates-java
sudo apt-get install libX11-dev libxext-dev libxrender-dev libxtst-dev
sudo apt-get install libasound2-dev libcups2-dev libfreetype6-dev
sudo apt-get install build-essential ruby-dev pkg-config
sudo apt-get install openjdk-6-jdk
sudo apt-get install fpm

mkdir /build/openjdk
cd /build/openjdk
git clone https://github.com/hgomez/obuildfactory.git

XBUILD=true ./obuildfactory/openjdk7/linux/standalone-job.sh

# List output file
ls OBF_DROP_DIR/openjdk7/
j2re-image-x86_64-u80-b05-20150127.tar.bz2
j2sdk-image-x86_64-u80-b05-20150127.tar.bz2

 

# Install to /opt/openjdk7
sudo mkdir /opt/openjdk7
cd /opt/openjdk7
sudo tar xvfj /build/openjdk/OBF_DROP_DIR/openjdk7/j2sdk-image-x86_64-u80-b05-20150127.tar.bz2

Android repo sync issus: gnutls_handshake failed

The issus was caused by gnutls library,  if network bandwidth is low

 

Fix:

Build git with openssl from source:

cat git_build.sh

GIT_MAJOR=1.7.9
GIT_MINOR=7
GIT_VER=${GIT_MAJOR}.${GIT_MINOR}
GIT_NAME=git-${GIT_VER}

OPENSSL_VER=1.0.1i
OPENSSL_NAME=openssl-${OPENSSL_VER}

CURL_VER=7.38.0
CURL_NAME=curl-${CURL_VER}

EXPAT_VER=2.1.0
EXPAT_NAME=expat-${EXPAT_VER}

TARGET_DIR=/usr/local/git-${GIT_MAIN}
TARGET_DIR=/tmp/local

BUILD_OPENSSL=0
BUILD_CURL=0
BUILD_EXPAT=0
BUILD_GIT=1

if [ “${BUILD_OPENSSL}” == “1” ];then
  if [ ! -f ${OPENSSL_NAME}.tar.gz ];then
    wget http://www.openssl.org/source/${OPENSSL_NAME}.tar.gz
  fi

  if [ -d ${OPENSSL_NAME} ];then
    rm -rf ${OPENSSL_NAME}
  fi

  tar xvfz ${OPENSSL_NAME}.tar.gz
  cd ${OPENSSL_NAME}

  ./config no-shared no-dso –prefix=${TARGET_DIR}
  make -j4
  #make test
  sudo make install
  cd ..
fi

if [ “${BUILD_CURL}” == “1” ];then
  if [ ! -f ${CURL_NAME}.tar.gz ];then
    wget http://curl.haxx.se/download/${CURL_NAME}.tar.gz
  fi

  if [ -d ${CURL_NAME} ];then
    rm -rf ${CURL_NAME}
  fi

  tar xvfz ${CURL_NAME}.tar.gz
  cd  ${CURL_NAME}
  env PKG_CONFIG_PATH=${TARGET_DIR}/lib/pkgconfig ./configure  –disable-shared –prefix=${TARGET_DIR} –without-gnutls –with-ssl
  make -j4
  sudo make install
  cd ..
fi

if [ “${BUILD_EXPAT}” == “1” ];then
  if [ ! -f ${EXPAT_NAME}.tar.gz ];then
    wget http://sourceforge.net/projects/expat/files/expat/${EXPAT_VER}/${EXPAT_NAME}.tar.gz
  fi

  if [ -d ${EXPAT_NAME} ];then
    rm -rf ${EXPAT_NAME}
  fi
  tar xvfz ${EXPAT_NAME}.tar.gz
  cd ${EXPAT_NAME}
  ./configure –disable-shared –prefix=${TARGET_DIR}
  make
  sudo make install
fi

if [ “${BUILD_GIT}” == “1” ];then
  if [ ! -f v${GIT_VER}.tar.gz ];then
    wget http://github.com/git/git/archive/v${GIT_VER}.tar.gz
  fi

 
  if [ -d ${GIT_NAME} ];then
    rm -rf ${GIT_NAME}
  fi

  tar xvfz v${GIT_VER}.tar.gz
  cd ${GIT_NAME}
  make configure
 
  ./configure –prefix=${TARGET_DIR}  –with-curl –with-openssl=${TARGET_DIR} –with-lib=${TARGET_DIR}

  make -j4
  #make test
  sudo make install
fi

Open Source Android SMS Gateway

Android Handset

Envaya: (outbound)

    http://sms.envaya.org/

    https://github.com/youngj/EnvayaSMS

 

SMSSync (inbond)

     http://smssync.ushahidi.com/

 

Increase the SMS Limit on Android:

http://www.xda-developers.com/android/increase-the-sms-limit-on-android/

Setting:

sms_outgoing_check_max_count=999999999999999999

Or:

sms_outgoing_check_interval_ms=0

 

 

Web Server:

SMStoXMPP

    https://projects.jethrocarr.com/p/oss-smstoxmpp/

Drupal

 

Android mount sdcard (again)

===>  execute_media_format
android/packages/apps/Settings/src/com/android/settings/MediaFormat.java

===>  mountService.formatVolume(extStoragePath);
android/frameworks/base/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java

====>  formatVolume
====>  doFormatVolume
android/frameworks/base/services/java/com/android/server/MountService.java

===> int CommandListener::VolumeCmd::runCommand
===> rc = vm->formatVolume(argv[2]);
android/system/vold/CommandListener.cpp

==> int VolumeManager::formatVolume
==> mVolumes = new VolumeCollection();
==> return v->formatVol()
android/system/vold/VolumeManager.h
android/system/vold/VolumeManager.cpp

===> int Volume::formatVol
===> Fat::format(devicePath, 0))
android/system/vold/Volume.cpp

===> int Fat::format(const char *fsPath, unsigned int numSectors)
===> static char MKDOSFS_PATH[] = “/system/bin/newfs_msdos”
android/system/vold/Fat.cpp

android/frameworks/base/services/java/com/android/server/NativeDaemonConnector.java

# C code
android/system/vold

# Launch sd formater in setting
adb shell
am start -n com.android.settings/.MediaFormat

##############################################################################

以下是打开“无线和网络设置”界面:

Intent intent = new Intent(“/”);
ComponentName cm = new ComponentName(“com.android.settings”,”com.android.settings.WirelessSettings”);
intent.setComponent(cm);
intent.setAction(“android.intent.action.VIEW”);
activity.startActivityForResult( intent , 0);

以下是可以直接打开的系统界面:

com.android.settings.AccessibilitySettings 辅助功能设置
com.android.settings.ActivityPicker 选择活动
com.android.settings.ApnSettings APN设置
com.android.settings.ApplicationSettings 应用程序设置
com.android.settings.BandMode 设置GSM/UMTS波段
com.android.settings.BatteryInfo 电池信息
com.android.settings.DateTimeSettings 日期和时间设置
com.android.settings.DateTimeSettingsSetupWizard 日期和时间设置
com.android.settings.DevelopmentSettings 应用程序设置=》开发设置
com.android.settings.DeviceAdminSettings 设备管理器
com.android.settings.DeviceInfoSettings 关于手机
com.android.settings.Display 显示——设置显示字体大小及预览
com.android.settings.DisplaySettings 显示设置
com.android.settings.DockSettings 底座设置
com.android.settings.IccLockSettings SIM卡锁定设置
com.android.settings.InstalledAppDetails 语言和键盘设置
com.android.settings.LanguageSettings 语言和键盘设置
com.android.settings.LocalePicker 选择手机语言
com.android.settings.LocalePickerInSetupWizard 选择手机语言
com.android.settings.ManageApplications 已下载(安装)软件列表
com.android.settings.MasterClear 恢复出厂设置
com.android.settings.MediaFormat 格式化手机闪存
com.android.settings.PhysicalKeyboardSettings 设置键盘
com.android.settings.PrivacySettings 隐私设置
com.android.settings.ProxySelector 代理设置
com.android.settings.RadioInfo 手机信息
com.android.settings.RunningServices 正在运行的程序(服务)
com.android.settings.SecuritySettings 位置和安全设置
com.android.settings.Settings 系统设置
com.android.settings.SettingsSafetyLegalActivity 安全信息
com.android.settings.SoundSettings 声音设置
com.android.settings.TestingSettings 测试——显示手机信息、电池信息、使用情况统计、Wifi information、服务信息
com.android.settings.TetherSettings 绑定与便携式热点
com.android.settings.TextToSpeechSettings 文字转语音设置
com.android.settings.UsageStats 使用情况统计
com.android.settings.UserDictionarySettings 用户词典
com.android.settings.VoiceInputOutputSettings 语音输入与输出设置
com.android.settings.WirelessSettings 无线和网络设置

##############################################################################
Generate SD Card Image file

#64G:
dd if=/dev/zero of=64G.img  count=0 seek=128M

#8G:
dd if=/dev/zero of=64G.img  count=0 seek=16M

#8G (with zero filled)
dd if=/dev/zero of=64G.img count=16M

##############################################################################
Loop device

#List loop devices:
losetup -a

#Add a loop device
losetup /dev/loop1 8G_zero.img

#Delete loop device
losetup -d /dev/loop1

find . -type f |xargs grep sd_format
find . -name *.java |xargs grep sd_format

###################################################################
Modify sd_format of android/packages/apps/Settings/res/values, impact on:

target R.java/Manifest.java: Settings (out/target/common/obj/APPS/Settings_intermediates/src/R.stamp)
target Java: Settings (out/target/common/obj/APPS/Settings_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Copying: out/target/common/obj/APPS/Settings_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/APPS/Settings_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/APPS/Settings_intermediates/classes.jar
Copying: out/target/common/obj/APPS/Settings_intermediates/noproguard.classes.jar
target Dex: Settings
Copying: out/target/common/obj/APPS/Settings_intermediates/noproguard.classes.dex
target Package: Settings (out/target/product/generic/obj/APPS/Settings_intermediates/package.apk)
‘out/target/common/obj/APPS/Settings_intermediates/classes.dex’ as ‘classes.dex’…
Processing target/product/generic/obj/APPS/Settings_intermediates/package.apk
Done!
Install: out/target/product/generic/system/app/Settings.odex
Install: out/target/product/generic/system/app/Settings.apk
Finding NOTICE files: out/target/product/generic/obj/NOTICE_FILES/hash-timestamp
Combining NOTICE files: out/target/product/generic/obj/NOTICE.html
target Java: SettingsTests (out/target/common/obj/APPS/SettingsTests_intermediates/classes)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Installed file list: out/target/product/generic/installed-files.txt
Target system fs image: out/target/product/generic/obj/PACKAGING/systemimage_intermediates/system.img
Install system fs image: out/target/product/generic/system.img

******************************************************
SD FORMAT

==> StorageVolumePreferenceCategory
==> mAllowFormat = mStorageVolume != null && !mStorageVolume.isEmulated()
android/packages/apps/Settings/src/com/android/settings/deviceinfo/StorageVolumePreferenceCategory.java

SD Card Mount

=> “Preparing SD card”
=> “Damaged SD card”
==> ext_media_checking_notification_title
==> ext_media_unmountable_notification_title
frameworks/base/core/res/res/values/strings.xml
frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
===>MEDIA_UNMOUNTABLE

*****************************************************

#/system/etc/vold.fatab
#/system/etc/vold.conf

=>fatab
==>system/vold/main.cpp
===>process_config
====>VolumeManager
=====>system/vold/VolumeManager.cpp
=======>CommandListener
========>system/vold/CommandListener.cpp

********************************
FAT
===> system/vold/Fat.cpp
====> FSCK_MSDOS_PATH
=====> Fat::check
======>system/vold/Volume.cpp
=======>createDeviceNode
=========>Volume::mountVol
=========>DirectVolume::handleBlockEvent

Volume::mountVol
==> No impact on SDCard Mount, just for security fs

DirectVolume::handleBlockEvent
==>NetlinkEvent
===>system/core/include/sysutils/NetlinkEvent.h
=====>NetlinkEvent.mSubsystem==”block”, send to volume manage ==> DirectVolume::handleBlockEvent
======>NlActionAdd
========>system/core/libsysutils/src/NetlinkEvent.cpp

==========>system/core/libsysutils/src/NetlinkListener.cpp
==========>NetlinkListener::onDataAvailable

============>system/core/libsysutils/src/SocketListener.cpp
============>system/core/include/sysutils/NetlinkListener.h
============>class NetlinkListener : public SocketListener

***************************************************************************************
*** Triger of  NlActionAdd ***

“add”:
=>NetlinkEvent::parseAsciiNetlinkMessage,    system/core/libsysutils/src/NetlinkEvent.cpp
==>NetlinkEvent::decode
===>NetlinkListener::onDataAvailable,        system/core/libsysutils/src/NetlinkListener.cpp
====>SocketListener::runListener,            system/core/libsysutils/src/SocketListener.cpp
=====>SocketListener::threadStart,           system/core/libsysutils/src/SocketListener.cpp
======>SocketListener::startListener,        system/core/libsysutils/src/SocketListener.cpp
=======>main,                                system/vold/main.cpp
=======>NetlinkHandler::start,               system/vold/NetlinkHandler.cpp

*** Handle of NlActionAdd ***

“NlActionAdd”
=>DirectVolume::handleBlockEvent,            system/vold/DirectVolume.cpp
==>VolumeManager::handleBlockEvent,          system/vold/VolumeManager.cpp
==>NetlinkHandler::onEvent,                  system/vold/NetlinkHandler.cpp

**************************************************************************
Framework:   MountService

frameworks/base/services/java/com/android/server/SystemServer.java
=>public MountService(Context context),     frameworks/base/services/java/com/android/server/MountService.java
==>mContext.registerReceiver(mBroadcastReceiver, filter, null, null);
===>BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
====>action.equals(Intent.ACTION_BOOT_COMPLETED)
=====>if (state.equals(Environment.MEDIA_UNMOUNTED)) {
int rc = doMountVolume(path);
if (rc != StorageResultCode.OperationSucceeded) {
Slog.e(TAG, String.format(“Boot-time mount failed (%d)”,
rc));
}
======>private int doMountVolume(String path)
=======>mConnector.doCommand(String.format(“volume mount %s”, path));

==>mConnector = new NativeDaemonConnector
===>class NativeDaemonConnector,    frameworks/base/services/java/com/android/server/NativeDaemonConnector
====>public void run(),             frameworks/base/services/java/com/android/server/NativeDaemonConnector.java
=====>listenToSocket,               frameworks/base/services/java/com/android/server/NativeDaemonConnector.java
======>mCallbacks.onDaemonConnected();     (mCallbacks=MountService)
=======>onDaemonConnected()         frameworks/base/services/java/com/android/server/MountService.java

**********************************************************************************
Sd Card Mount Summary:

frameworks/base/services/java/com/android/server/MountService.java:
private int doMountVolume(String path):

Use case of doMountVolume

Case 1:  private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
===> Boot up SD Card mount

Case 2:  public boolean onEvent(int code, String raw, String[] cooked)
===>frameworks/base/services/java/com/android/server/NativeDaemonConnector.java
===>Callback
===>public boolean handleMessage(Message msg)
===> SD Card Insert mount

Case 3: public int mountVolume(String path)
==> packages/apps/Settings/src/com/android/settings/deviceinfo/Memory.java
==> User Setting/Mount

Case 4: public int mountVolume(String path)
===> frameworks/base/core/java/com/android/internal/os/storage/ExternalStorageFormatter.java
===> Factory Reset

Download android source code over SSH

1) Install http proxy with socks support
sudo apt-get install privoxy

2) Install DNS cache server
sudo apt-get install dnsmasq

3) Install DNS socks proxy
git clone https://github.com/jtRIPper/dns-tcp-socks-proxy.git
cd dns-tcp-socks-proxy
make

4) Setup ssh connection to the external server, and listen on port 127.0.0.1:4567 (any one free)

ssh -p proto -D4567 user@ssh_server

5) Config privoxy listen on 127.0.0.1:8080, and forward to ssh socks at 127.0.0.1:4567:

cat /etc/privoxy/config
listen-address 127.0.0.1:8080
forward-socks5 / 127.0.0.1:4567 .

forward 192.168.*.*/ .
forward 10.*.*.*/ .
forward 127.*.*.*/ .

6) Config dnsmasq with upstream server point to dns-tcp-socks-proxy first

cat /etc/dnsmasq.conf

resolv-file=/etc/resolv-dnsmasq.conf
strict-order
server=/221.24.172.in-addr.arpa/internal_dns_ip
server=/61.24.172.in-addr.arpa/internal_dns_ip
server=/62.24.172.in-addr.arpa/internal_dns_ip
server=/63.24.172.in-addr.arpa/internal_dns_ip
interface=eth0
bind-interfaces
log-queries
log-dhcp

With such configuration, dnsmasq will listen on eth0 interface and 127.0.0.1, and forward the query to the DNS resolver defined in /etc/resolv-dnsmasq.conf.
the strict-order directory force dnsmasq to select the dns server according to the order of item defined in /etc/resolv-dnsmasq.conf

cat /etc/resolv-dnsmasq.conf
nameserver 127.0.0.2
nameserver 172.24.63.211
nameserver 172.24.63.212

7) Config dns-tcp-socks-proxy listen to dnsmasq, and forward the query to the ssh socks, here 127.0.0.1:4567

cat dns_proxy.conf
socks_port = 4567
socks_addr = 127.0.0.1

listen_addr = 127.0.0.2
listen_port = 53

set_user = nobody
set_group = nobody

resolv_conf = /etc/dns_proxy/resolv.txt
log_file = /dev/null

8) Config the local dns resolver to 127.0.0.1
cat /etc/resolv.conf
nameserver 127.0.0.1

9) Sync android source code over SSH
repo sync

10) Note, with such configuration, we have:
http/https local proxy at 127.0.0.1:8080, forward to the external server via socks
dns local cache proxy at 127.0.0.1:53, forward to the external server vis socks