android开发中积累的小知识

来源:互联网 发布:js object push 编辑:程序博客网 时间:2024/05/16 09:06
一:开机logo ,在根路径7627a_splash下把图片放入,运行splash.sh文件
然后再把splash.txt中的值复制粘帖在bootable/bootloader/lk/target/项目名/include/target/的splash.h文件中
再make aboot

把out/target/product/项目名/下面(emmc_appsboot.mbn,emmc_appsboothd.mbn)这个是针对与emmc,或者是(appsboot.mbn,appsboothd.mbn)这个是针对nand。把这2个文件考出来,在window下用qts烧写进去。


二:修改开关机动画
把制作好的bootanimation.zip和shutdownanimation.zip放到 /system/core/rootdir/项目名/。

可以直接push到机器的system/media下面,重启就可以看到效果


三:判断项目名
import android.os.SystemProperties;
private boolean mIsA100 = "msm7627a_v12_a100".equals(SystemProperties.get("ro.product.name"));


if("1".equals(SystemProperties.get("persist.sys.emmcsdcard.enabled")))这是把内存设在为内部存储

在cpp文件中
#include <cutils/properties.h>
char value[PROPERTY_VALUE_MAX];
property_get("sys.secpolicy.camera.disabled", value, "0");获取值


四:查看某个人的所以提交 git log --author="xxxx"

五:进入fastboot模式,可以命令adb reboot-bootloader,#*20110606#打开测试开关

六:添加USB,在/etc/udev/rules.d下

七:  
Intent.ACTION_USER_PRESENT这个为解锁的广播
KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);  
     
    if (mKeyguardManager.inKeyguardRestrictedInputMode()) {
       为锁屏状态
    }
八:检测耳机是否插入 public boolean checkHeadSet() {
        AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        return audio.isWiredHeadsetOn();
    }

Intent.ACTION_HEADSET_PLUG这个为监听耳机的插拔

九:给应用分配最小的内存
VMRuntime.getRuntime()
                .setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
        VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);
    private final static float TARGET_HEAP_UTILIZATION = 0.75f;

    private final static int CWJ_HEAP_SIZE = 6 * 1024 * 1024;

十:monkey测试的命令
adb shell monkey -v -p com.android.XXX --pct-nav 0 --pct-majornav 0 --pct-anyevent 0 --ignore-security-exceptions --throttle 100 -v 50000

十一:不通过数据库直接获取视频第一帧
public static Bitmap createVideoThumbnail(Context context, Uri uri) {
                Bitmap bitmap = null;
                String className = "android.media.MediaMetadataRetriever";
                Object objectMediaMetadataRetriever = null;
                Method release = null;

                try {

objectMediaMetadataRetriever = Class.forName(className).newInstance();
                      Method setModeMethod = Class.forName(className).getMethod("setMode", int.class);
                      setModeMethod.invoke(objectMediaMetadataRetriever,
                                        MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);

 Method setDataSourceMethod = Class.forName(className).getMethod(
                                        "setDataSource", Context.class, Uri.class);
                      setDataSourceMethod.invoke(objectMediaMetadataRetriever, context,uri);

Method captureFrameMethod = Class.forName(className).getMethod("captureFrame");
                      release = Class.forName(className).getMethod("release");

                      bitmap = (Bitmap) captureFrameMethod
                                        .invoke(objectMediaMetadataRetriever);

} catch (Exception e) {
                        e.printStackTrace();
                } finally {try {
                                if (release != null) {
                                        release.invoke(objectMediaMetadataRetriever);
                                }
                        } catch (Exception e) {

// Ignore failures while cleaning up.
                                e.printStackTrace();
                        }
                }
                return bitmap;
        }

十二:8x25系列camera配置
后摄 500 万 ov5640 ov5647 s5k4e1已经添加
前摄 30万 gc0339 ov9726  ov7692 也已添加
kernel/arch/arm/configs/msm8x25_d8_eg530-perf_defconfig

十三:判断music是否在播放
 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                        if(audioManager.isMusicActive())
{
......}


十四:杀死本进程

android.os.Process.killProcess(android.os.Process.myPid());

十五:抓取log
1:带有时间的log:  adb logcat -v time >>log.txt
2:把log保存在手机里面,这时候可以在后台运行
adb shell; logcat -vtime >data/log.txt &

十六:选择编译,例如在Android.mk里面,如果msm8x25q_d10_j320c项目,则编译d10_j320c/AndroidManifest.xml这个文件。
    ifneq (, $(filter msm8x25q_d10_j320c, $(TARGET_PRODUCT)))
    LOCAL_MANIFEST_FILE := d10_j320c/AndroidManifest.xml
    endif

十七:外部U盘无法挂载
在DOS中键入, chkdsk F: /f 

十八:隐藏输入法
1:隐藏其他应用打开的输入法
 InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                              if (imm != null) {
                                  imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                             
2:隐藏本应用打开的输入法
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    inputMethodManager.hideSoftInputFromWindow(OpeListActivity.this.getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);

十九:camera的翻转
有两个地方可以改,但是这个要是情况而定,改其中一个
1:在CameraService.cpp中的sendCommand中

if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
        // Mirror the preview if the camera is front-facing.
        bool isqqpimsecure = false;
        if (mCameraFacing == CAMERA_FACING_FRONT) {
            int fd;
            char buf[1024] = {0};



snprintf(buf,1024,"/proc/%d/cmdline",getCallingPid());
            if ((fd = open(buf,O_RDONLY)) != -1) {
                if((read(fd, buf, 1023)) != -1) {
                    ALOGE("sendCommand pid=%d, pname=%s", getCallingPid(), buf);
                }
                close(fd);

            }

if (strcmp(buf, "com.tencent.qqpimsecure") == 0 || strcmp(buf, "com.tencent.mobileqq") == 0 || strcmp(buf, "com.tencent.mobileqq:video") == 0) {
                ALOGE("sendCommand pid=%d, pname=%s modifty 180 for com.tencent.qqpimsecure", getCallingPid(), buf);
                isqqpimsecure = true;
            }
        }

orientation = getOrientation(isqqpimsecure ? (arg1 + 180) : arg1, mCameraFacing == CAMERA_FACING_FRONT);
        if (orientation == -1) return BAD_VALUE;
if (mOrientation != orientation) {
            mOrientation = orientation;
            if (mPreviewWindow != 0) {
                native_window_set_buffers_transform(mPreviewWindow.get(),
                        mOrientation);
            }
        }
        return OK;
    }

2:在CameraService.cpp中的getCameraInfo修改。

status_t CameraService::getCameraInfo(int cameraId,
                                      struct CameraInfo* cameraInfo) {
    if (!mModule) {
        return NO_INIT;
    }

    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
        return BAD_VALUE;
    }

struct camera_info info;
    status_t rc = mModule->get_camera_info(cameraId, &info);
    cameraInfo->facing = info.facing;
    cameraInfo->orientation = info.orientation;
    if (cameraId == CAMERA_FACING_FRONT) {
        int fd;
        char buf[1024] = {0};
    char value2[PROPERTY_VALUE_MAX];
        property_get("ro.product.name", value2, "0");
        bool isv10_yd=false;
        if(strcmp(value2,"msm8x25_v10_w656_yd")==0){
           isv10_yd=true;
        }

snprintf(buf,1024,"/proc/%d/cmdline",getCallingPid());
        if ((fd = open(buf,O_RDONLY)) != -1) {
            if((read(fd, buf, 1023)) != -1) {
                LOGE("getCameraInfo pid=%d, pname=%s", getCallingPid(), buf);
            }
            close(fd);
        }

if (!isv10_yd && strcmp(buf, "com.tencent.mm") == 0) {
            LOGE("getCameraInfo pid=%d, pname=%s modifty 180 for weixin", getCallingPid(), buf);
            cameraInfo->orientation += 180;
        }else if(strcmp(buf, "com.google.android.talk")==0){
            cameraInfo->orientation += 180;
        }
    }
    return rc;
}

二十:当手机没有权限的时候,以下方法可以获取权限,进行install或者push.

#mount
# mount -o  remount /dev/block/mtdblock1 /system
# chmod 777 system/app

二十一:CTStest

4.1平台cts命令:单测试某个case: run cts -c class name -m case name 比如:run cts -c android.hardware.cts.CameraGLTest -m testCameraToSurfaceTextureMetadata
         测试一个包: run cts -c class name; 比如:run cts -c android.hardware.cts.CameraGLTest


2.3平台cts命令:单测试某个case : start --plan CTS -t class name#case name ,比如,start --plan CTS -t android.hardware.cts.CameraGLTest#testCameraToSurfaceTextureMetadata
     测试一个包:start --plan CTS -p class name, 比如: start --plan CTS -p android.hardware.cts.CameraGLTest

二十二:抓起tcpdump信息,tcpdump -i any -p -s 0 -w /sdcard/pcap.pcap

二十三:防止OOM代码

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {
        if (width > height) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        } else {
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return inSampleSize;

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

二十四:查看总内存信息:cat proc/meminfo

二十五:特殊符合表示

+-×÷
Java中使用+\u2212\u00d7\u00f7表示

二十六:使用命名合patch.
你现在有一个code base: small-src, 你的patch文件放在~/patch/0001-trival-patch.patch

cd small-src
git-am ~/patch/0001-trival-patch.patch

二十七:抓起视频DUMP

1.Dump bit steam and outout yuv data
please run the below command before you test.
adb shell
// dump output yuv
setprop vidc.dec.log.out 1
//dump bit stream
setprop vidc.dec.log.in 1
You shall have the write permission in /data/misc/media

You will find the bitsteam and yuv data on /data/misc/media


2.Enable log.
please run the below command before you test.
a).Enable the omx debug
adb shell setprop vidc.debug.level 7
b.Enable the kernel log
adb shell

su
cd /d/msm_vidc
echo 0x1003 > debug_level
echo 0x3F > fw_level

二十八:命令输入字符串到Edittext里面
adb shell input text  asdfsff

二十九:打印数组的内容:
直接打印Arrays.toString(数组名) 即可。

三十:网络部分
获取网络信息需要在AndroidManifest.xml文件中加入相应的权限。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1)判断是否有网络连接

public boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}

2)判断WIFI网络是否可用

public boolean isWifiConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWiFiNetworkInfo != null) {
return mWiFiNetworkInfo.isAvailable();
}
}
return false;
}

3)判断MOBILE网络是否可用
public boolean isMobileConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mMobileNetworkInfo = mConnectivityManager
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (mMobileNetworkInfo != null) {
return mMobileNetworkInfo.isAvailable();
}
}
return false;
}

4)获取当前网络连接的类型信息

public static int getConnectedType(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
return mNetworkInfo.getType();
}
}
return -1;
}

在开发android应用时,涉及到要进行网络访问,时常需要进行网络状态的检查,以提供给用户必要的提醒。一般可以通过ConnectivityManager来完成该工作。
ConnectivityManager有四个主要任务:
1、监听手机网络状态(包括GPRS,WIFI, UMTS等)
2、手机状态发生改变时,发送广播

3、当一个网络连接失败时进行故障切换
4、为应用程序提供可以获取可用网络的高精度和粗糙的状态
当我们要在程序中监听网络状态时,只要一下几个步骤即可:
1、定义一个Receiver重载其中的onReceive函数,在其中完成所需要的功能,如根据WIFI和GPRS是否断开来改变空间的外观

connectionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectMgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mobNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifiNetInfo = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

if (!mobNetInfo.isConnected() && !wifiNetInfo.isConnected()) {
Log.i(TAG, "unconnect");
// unconnect network
}else {
// connect network
}
}
};

2、在适当的地方注册Receiver,可以在程序中注册,在onCreate中调用如下函数即可:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectionReceiver, intentFilter);

3、在适当时取消注册Receiver,可以在程序中取消,在onDestroye中调用如下函数即可:
if (connectionReceiver != null) {
unregisterReceiver(connectionReceiver);
}

关于使用TelephonyManager 的方法的

final TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
mTelephonyMgr.listen(new PhoneStateListener(){
@Override
public void onDataConnectionStateChanged(int state) {
switch(state){
case TelephonyManager.DATA_DISCONNECTED://网络断开
break;
case TelephonyManager.DATA_CONNECTING://网络正在连接
break;
case TelephonyManager.DATA_CONNECTED://网络连接上
break;
}
}
}, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);

至于第二种方法,本人并没有去尝试过。第一种方式还是比较好用,如果要程序隐藏在后台的话,建议开个service,将BroadcastReceiver注册在service,但不要忘了取消注册。
在测试中遇到过这样的状况,将一个当前连接wifi的路由设备关闭,但是程序并没有捕捉到unconnect network,可能是因为手机设备立刻连接另一个路由设备了。
Android 监控网络状态

public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
Log.i("NetWorkState", "Unavailabel");
return false;
} else {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
Log.i("NetWorkState", "Availabel");
return true;
}
}
}
}
return false;
}

上面这个方法就是判断网络是否连接的代码,返回true表示有网络,返回false表示无网络。 在Android网络应用程序开发中,经常要判断网络连接是否可用,因此经常有必要监听网络状态的变化。android的网络状态监听可以用BroadcastReceiver来接收网络状态改变的广 播,具体实现如下:

@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "网络状态改变");
boolean success = false;
//获得网络连接服务
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
// State state = connManager.getActiveNetworkInfo().getState();
State state = connManager.getNetworkInfo(
ConnectivityManager.TYPE_WIFI).getState(); // 获取网络连接状态
if (State.CONNECTED == state) { // 判断是否正在使用WIFI网络
success = true;
}

state = connManager.getNetworkInfo(
ConnectivityManager.TYPE_MOBILE).getState(); // 获取网络连接状态
if (State.CONNECTED != state) { // 判断是否正在使用GPRS网络
success = true;
}
if (!success) {
Toast.makeText(LocationMapActivity.this, "您的网络连接已中断", Toast.LENGTH_LONG).show();
}
}

//注册网络监听
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mNetworkStateReceiver, filter);
//在Activity中的onDestroy中:'
unregisterReceiver(mNetworkStateReceiver); //取消监听

很多朋友在android开发中,都会遇到手机网络类型判断,因为就目前的android平台手机来说:可能会存在4中状态
1.无网络(这种状态可能是因为手机停机,网络没有开启,信号不好等原因)
2.使用WIFI上网

3.CMWAP(中国移动代理)
4.CMNET上网
这四种状态,如果没有网络,肯定是无法请求Internet了,如果是wap就需要为手机添加中国移动代理,关于为手机添加中国移动的代理,请到
下面是网络判断的方法:

/**
* 获取当前的网络状态 -1:没有网络 1:WIFI网络2:wap网络3:net网络
* @param context
* @return
*/

public static int getAPNType(Context context){
int netType = -1;
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if(networkInfo==null){
return netType;
}

int nType = networkInfo.getType();
if(nType==ConnectivityManager.TYPE_MOBILE){
Log.e("networkInfo.getExtraInfo()", "networkInfo.getExtraInfo() is "+networkInfo.getExtraInfo());
if(networkInfo.getExtraInfo().toLowerCase().equals("cmnet")){
netType = CMNET;
}
else{
netType = CMWAP;
}
}
else if(nType==ConnectivityManager.TYPE_WIFI){
netType = WIFI;
}
return netType;
}

三十一:流媒体网址以及各平台BuildId
流媒体测试网址:
http://218.206.176.104:8080/portalone/test.jsp  2009
AD681h调试模式:*#06#下查看MEID和IMEI

8926平台:M8926AAAAANLYD1130003.2   
8x10平台:M8610AAAAANLYD1935   
8x10 2+2平台:M8610AAAAMWLYD190240.2

8916平台,项目选X1_CT,build ID:M8916AAAAANLYD1127.2
8x10-kk android4.4(kk)的build id:M8610BAAAANAZM203044.1
8x25 平台:R8625SSNSKQLY10145451

三十二:
1: In device, /system.build.prop file, make sure ro.qualcomm.cabl=0
2: In device,  /init.qcom.rc  file, make sure remove the below information, (/system/bin, make sure remove mm-pp-daemon)
/device/qcom/common/rootdir/etc/init.qcom.rc 

comment as below 
#service ppd /system/bin/mm-pp-daemon 
# class late_start 
# user system 
# socket pps stream 0660 system system graphics 
# group system graphics

3: In device, /system/app/, make sure delete CABLService.apk, PPPreference.apk, SVIService.apk as well.

三十三:系统优先级
Android将进程分为6个等级,它们按优先级顺序由高到低依次是:
   1.前台进程( FOREGROUND_APP)
   2.可视进程(VISIBLE_APP )
   3. 次要服务进程(SECONDARY_SERVER )
   4.后台进程 (HIDDEN_APP)

   5.内容供应节点(CONTENT_PROVIDER)

   6.空进程(EMPTY_APP)
特征:

1.如果一个进程里面同时包含service和可视的activity,那么这个进程应该归于可视进程,而不是service进程。
2.另外,如果其他进程依赖于它的话,一个进程的等级可以提高。例如,一个A进程里的service被绑定到B进程里的组件上,进程A将总被认为至少和B进程一样重要。
3.系统中的phone服务被划分到前台进程而不是次要服务进程.

在android中,进程的oom_adj值也就代表了它的优先级。oom_adj值越高代表该进程优先级越低。文件/init.rc中有以下属性设置:
    setprop ro.FOREGROUND_APP_ADJ       0
    setprop ro.VISIBLE_APP_ADJ                     1
    setprop ro.SECONDARY_SERVER_ADJ   2
    setprop ro.HIDDEN_APP_MIN_ADJ           7
    setprop ro.CONTENT_PROVIDER_ADJ  14
    setprop ro.EMPTY_APP_ADJ                    15

/init.rc中,将PID为1的进程(init进程)的oom_adj设置为SYSTEM_ADJ(-16):
    # Set init its forked children's oom_adj.
    write /proc/1/oom_adj -16
查看本机设置:
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,7,14,15

回收时机:
文件/init.rc中:
   setprop ro.FOREGROUND_APP_MEM       1536      //    6M
   setprop ro.VISIBLE_APP_MEM                     2048     //    8M
   setprop ro.SECONDARY_SERVER_MEM   4096     //  16M
   setprop ro.HIDDEN_APP_MEM                     5120     //  20M
   setprop ro.CONTENT_PROVIDER_MEM    5632     //  22.4M
   setprop ro.EMPTY_APP_MEM                      6144     //  24M

这些数字也就是对应的内存阈值,一旦低于该值,Android便开始按顺序关闭相应等级的进程。
注意这些数字的单位是page: 1 page = 4 kB。所以上面的六个数字对应的就是(MB): 6,8,16,20,22,24。

查看现在的内存阈值设置:
cat /sys/module/lowmemorykiller/parameters/minfree


要想重新设置该值(对应不同的需求):
echo   "1536,2048,4096,5120,15360,23040">/sys/module/lowmemorykiller/parameters/minfree
这样当可用内存低于90MB的时候便开始杀死"空进程",而当可用内存低于60MB的时候才开始杀死"内容供应节点"类进程。

三十四:使用命令nautilus . 直接打开当前文件夹

三十五:通过backtrace信息反编译地址
例如:
I/DEBUG   (  230): backtrace:

I/DEBUG   (  230):     #00  pc 00002230  /system/vendor/lib/libcneconn.so (std::priv::_Rb_global<bool>::_Rebalance_for_erase(std::priv::_Rb_tree_node_base*, std::priv::_Rb_tree_node_base*&, std::priv::_Rb_tree_node_base*&, std::priv::_Rb_tree_node_base*&)+372)


I/DEBUG   (  230):     #01  pc 000037f0  /system/vendor/lib/libcneconn.so (removeFd+96)


I/DEBUG   (  230):     #02  pc 00005e1c  /system/vendor/lib/libcneconn.so (close+100)

I/DEBUG   (  230):     #03  pc 00000d35  /system/vendor/lib/libNimsWrap.so (close+16)


I/DEBUG   (  230):     #04  pc 00206773  /system/lib/libwebviewchromium.so //以这个为例子


I/DEBUG   (  230):     #05  pc 00206909  /system/lib/libwebviewchromium.so

I/DEBUG   (  230):     #06  pc 002069a1  /system/lib/libwebviewchromium.so


那么使用以下命令就可以
./prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-addr2line -f -e out/target/product/msm8916_x1_p520l/sybmol/system/lib/libwebviewchromium.so  00206773


三十五:系统内存相关计算
private ActivityManager mAm;
private long SECONDARY_SERVER_MEM;
private MemInfoReader mMemInfoReader = new MemInfoReader();
private long mMB = 1024 * 1024;

ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
 mAm.getMemoryInfo(memInfo);
 SECONDARY_SERVER_MEM = memInfo.secondaryServerThreshold;

long totalMemory = Runtime.getRuntime().totalMemory() / mMB;
 long freeMemory = Runtime.getRuntime().freeMemory() / mMB;
 long maxMemory = Runtime.getRuntime().maxMemory() / mMB;
  
 long remainMemory = maxMemory - totalMemory;

mMemInfoReader.readMemInfo();
 long freeSize = mMemInfoReader.getFreeSize();
 long cachedSize = mMemInfoReader.getCachedSize();
 long availMem = freeSize + cachedSize - SECONDARY_SERVER_MEM;

三十六:高通的一些调试命令:
1:录制操作步骤:
screenrecord sdcard/video.mp4
2:获取preview 的fps

adb shell setprop persist.debug.sf.showfps  1
在log中搜索关键字 PROFILE_PREVIEW_FRAMES_PER_SECOND
3:视频编解码类Log
(1). User space
>adb root
>adb shell setprop vide.debug.level 7

这个命令会打开User space中视频编解码相关详细Log.
(2). Kernel Driver
>adb root
>adb shell
#cd /d/msm_vidc

#echo 0x101f > debug_level //打开video kernel driver详细Log
#echo 0x3f > fw_level //打开video firmware Log

4:视频编解码Input和Output buffer logs
(1). 视频解码Input和Output buffer logs
>adb root

>chmod 777 /data/msic/media
>adb shell setprop vidc.dec.log.out 1 //enable output buffer log
>adb shell setprop vidc.dec.log.in 1 //enable input buffer log

(2) 视频编码Input和Output buffer logs
>adb root
>chmod 777 /data/msic/media
>adb shell setprop vidc.dec.log.out 1 //enable output buffer log
>adb shell setprop vidc.dec.log.in 1 //enable input buffer log

5:视频Android Framework的Log
根据测试场景的不同, 相应的Framework log开关需要打开. 下面分别说明.

1. 本地视频文件播放
mediaplayer.cpp
AwesomePlayer.cpp
OMXCodec.cpp
MPEG4Extractor.cpp
MediaPlayerService.cpp
AudioPlayer.cpp

2. 录像
StagefrightRecorder.cpp
OmxCodec.cpp
CameraSource.cpp
MPEG4Writer.cpp

3. HTTP流媒体
mediaplayer.cpp, 
Awesomeplayer.cpp 
OMXCodec.cpp
MPEG4Extractor.cpp
NuCachedSource2.cpp 
chromium_http/ChromiumHTTPDataSource.cpp
chromium_http/support.cpp

4. RTSP流媒体
mediaplayer.cpp
NuPlayer.cpp
NuPlayerRenderer.cpp
NuPlayerDriver.cpp
ACodec.cpp
MediaCodec.cpp
RTSPSource.cpp
MyHandler.h
ARTPConnection.cpp
ARTSPConnection.cpp

5:5. HTTP Live Streaming(HLS)
NuPlayer.cpp
NuPlayerRenderer.cpp
ACodec.cpp
LiveSession.cpp
HTTPLiveSource.cpp
NuPlayerDriver.cpp
MediaCodec.cpp

打开Framework Log方法:
在要打开Log的文件头部增加
#define LOG_NDEBUG 0
#define LOG_NIDEBUG 0
#define LOG_NDDEBUG 0

三十七:如果机器出现很卡的情况,可以清除drop_caches
adb shell
#sync
#echo 3 > /proc/sys/vm/drop_caches 

三十八:软件截屏
/**
         * 获取当前屏幕截图
         *
         * @param activity
         * @return
         */

        public static Bitmap screenShot(Activity activity)
        {
                View view = activity.getWindow().getDecorView();
                view.setDrawingCacheEnabled(true);
                view.buildDrawingCache();
                Bitmap bmp = view.getDrawingCache();
                Rect frame = new Rect();

                activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
                int statusBarHeight = frame.top;

                int width = getScreenWidth(activity);
                int height = getScreenHeight(activity);
                Bitmap bp = null;

                bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height
                                - statusBarHeight);
                view.destroyDrawingCache();
                return bp;

        }

三十九:打印堆栈信息
    public static void printCallStatck() {
        Throwable ex = new Throwable();
        StackTraceElement[] stackElements = ex.getStackTrace();
        if (stackElements != null) {
            for (int i = 0; i < stackElements.length; i++) {
                Log.i("zhou", stackElements[i].getClassName() + "===="
                        + stackElements[i].getFileName() + "====="
                        + stackElements[i].getLineNumber() + "==="
                        + stackElements[i].getMethodName()===);
            }
        }
    }


四十:语言查询
Values文件汇总如下

中文(中国):values-zh-rCN
中文(台湾):values-zh-rTW
中文(香港):values-zh-rHK
英语(美国):values-en-rUS
英语(英国):values-en-rGB
英文(澳大利亚):values-en-rAU
英文(加拿大):values-en-rCA
英文(爱尔兰):values-en-rIE
英文(印度):values-en-rIN
英文(新西兰):values-en-rNZ
英文(新加坡):values-en-rSG

英文(南非):values-en-rZA
阿拉伯文(埃及):values-ar-rEG
阿拉伯文(以色列):values-ar-rIL
保加利亚文:  values-bg-rBG
加泰罗尼亚文:values-ca-rES
捷克文:values-cs-rCZ
丹麦文:values-da-rDK

德文(奥地利):values-de-rAT
德文(瑞士):values-de-rCH
德文(德国):values-de-rDE
德文(列支敦士登):values-de-rLI
希腊文:values-el-rGR
西班牙文(西班牙):values-es-rES
西班牙文(美国):values-es-rUS

芬兰文(芬兰):values-fi-rFI
法文(比利时):values-fr-rBE
法文(加拿大):values-fr-rCA
法文(瑞士):values-fr-rCH
法文(法国):values-fr-rFR
希伯来文:values-iw-rIL
印地文:values-hi-rIN

克罗里亚文:values-hr-rHR
匈牙利文:values-hu-rHU
印度尼西亚文:values-in-rID
意大利文(瑞士):values-it-rCH
意大利文(意大利):values-it-rIT
日文:values-ja-rJP
韩文:values-ko-rKR

立陶宛文:valueslt-rLT
拉脱维亚文:values-lv-rLV
挪威博克马尔文:values-nb-rNO
荷兰文(比利时):values-nl-BE
荷兰文(荷兰):values-nl-rNL
波兰文:values-pl-rPL


葡萄牙文(巴西):values-pt-rBR
葡萄牙文(葡萄牙):values-pt-rPT
罗马尼亚文:values-ro-rRO
俄文:values-ru-rRU
斯洛伐克文:values-sk-rSK

斯洛文尼亚文:values-sl-rSI
塞尔维亚文:values-sr-rRS
瑞典文:values-sv-rSE
泰文:values-th-rTH
塔加洛语:values-tl-rPH
土耳其文:values--r-rTR
乌克兰文:values-uk-rUA
越南文:values-vi-rVN






2 0