Pages:  1 2 ... 15 16 17 18 19 20 21 22
lytsing – Page 18 – lytsing's Blog

Author: lytsing

  • 强悍的Android反编apk译软件 apktool

    apktool 下载地址: http://code.google.com/p/android-apktool/
    使用说明上面的链接也写非常清楚,需要注意的就是java是1.6版本的。

    前段时间整理了一个 wiki文档 http://lytsing.org/wiki/android/decompile.html ,简要列出了三个反编译工具:

    • smali
    • dedexer
    • dexdump

    今天下午与absurd老大聊了一下,他说apktool很强大,于是G它一把,看到youtubu有两个视频:

    Apktool Demo 1 – Editing HTC_IME resources

    Apktool Demo 2 – Smali improvements

    视频请自行翻墙观看。视频还有人留言:”Fantastic! Simply Awesome. Thanks so much, I will be looking for your dontate button” . Laugh!人家弄个软件也不容易啊。

    AndroidManifest.xml 一般用 AXMLPrinter2.jar 反编译后,勉强看懂,但还有一些字符串没翻译,apktool做的更彻底,一步到位。不过用AXMLPrinter2.jar反编译xml文件输出的结果很整齐美观。用Eclipse格式化layout的xml文件,结果不那么令人满意。在Jeff Sharkey的一篇博文中,他说Roman Guy会把xml格式化很漂亮,为此,曾经给Roman Guy发过邮件,至今没得到回复:(

    用dedexer反编译出来的ddx文件,参数名没显示出来,

    .method public static getSearchQueryForPublisher(Ljava/lang/String;)Ljava/lang/String;
    .limit registers 3
    ; parameter[0] : v2 (Ljava/lang/String;)

    apktool 反编译出来的smali文件,参数名都列出来了:

    .method public static getSearchQueryForPublisher(Ljava/lang/String;)Ljava/lang/String;
        .locals 2
        .parameter "publisher"

    用dedexer反编译出来的ddx格式文件,可读性会好一些。

    youtube的视频演示了如何修改代码,然后重新打包,签名发布。至于用来汉化,更是小case。同时,从另一个方面来讲,Android程序的安全问题也很是忧虑。

    apktool令人感到震撼,我那wiki页面信息全out了。

  • 一个封装 android.util.Log 的Log类

    在android代码的每个Activity,都不厌其烦的写:

    private static final String TAG = "MyActivity";

    然后需要打印的地方输入:

    Log.v(TAG, "index=" + i);

    写太多的TAG,也麻烦,如果不写TAG,用 this.toString() 也可行,不过还是一样,于是写个包装Log类,自动处理是哪个Activity,调用哪个函数,如下:

    /*
     * Copyright (C) 2010 Lytsing Huang http://lytsing.org
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    package org.lytsing.android.util;
    
    /**
     * Wrapper API for sending log output.
     */
    public class Log {
        protected static final String TAG = "MyApplication";
    
        public Log() {
        }
    
        /**
         * Send a VERBOSE log message.
         * @param msg The message you would like logged.
         */
        public static void v(String msg) {
            android.util.Log.v(TAG, buildMessage(msg));
        }
    
        /**
         * Send a VERBOSE log message and log the exception.
         * @param msg The message you would like logged.
         * @param thr An exception to log
         */
        public static void v(String msg, Throwable thr) {
            android.util.Log.v(TAG, buildMessage(msg), thr);
        }
    
        /**
         * Send a DEBUG log message.
         * @param msg
         */
        public static void d(String msg) {
            android.util.Log.d(TAG, buildMessage(msg));
        }
    
        /**
         * Send a DEBUG log message and log the exception.
         * @param msg The message you would like logged.
         * @param tr An exception to log
         */
        public static void d(String msg, Throwable thr) {
            android.util.Log.d(TAG, buildMessage(msg), thr);
        }
    
        /**
         * Send an INFO log message.
         * @param msg The message you would like logged.
         */
        public static void i(String msg) {
            android.util.Log.i(TAG, buildMessage(msg));
        }
    
        /**
         * Send a INFO log message and log the exception.
         * @param msg The message you would like logged.
         * @param thr An exception to log
         */
        public static void i(String msg, Throwable thr) {
            android.util.Log.i(TAG, buildMessage(msg), thr);
        }
    
        /**
         * Send an ERROR log message.
         * @param msg The message you would like logged.
         */
        public static void e(String msg) {
            android.util.Log.e(TAG, buildMessage(msg));
        }
    
        /**
         * Send a WARN log message
         * @param msg The message you would like logged.
         */
        public static void w(String msg) {
            android.util.Log.w(TAG, buildMessage(msg));
        }
    
        /**
         * Send a WARN log message and log the exception.
         * @param msg The message you would like logged.
         * @param thr An exception to log
         */
        public static void w(String msg, Throwable thr) {
            android.util.Log.w(TAG, buildMessage(msg), thr);
        }
    
        /**
         * Send an empty WARN log message and log the exception.
         * @param thr An exception to log
         */
        public static void w(Throwable thr) {
            android.util.Log.w(TAG, buildMessage(""), thr);
        }
        
        /**
         * Send an ERROR log message and log the exception.
         * @param msg The message you would like logged.
         * @param thr An exception to log
         */
        public static void e(String msg, Throwable thr) {
            android.util.Log.e(TAG, buildMessage(msg), thr);
        }
    
        /**
         * Building Message
         * @param msg The message you would like logged.
         * @return Message String
         */
        protected static String buildMessage(String msg) {      
            StackTraceElement caller = new Throwable().fillInStackTrace().getStackTrace()[2];
    
             return new StringBuilder()
                    .append(caller.getClassName())
                    .append(".")
                    .append(caller.getMethodName())
                    .append("(): ")
                    .append(msg).toString();
        }
    }
    

    LogDemo.java:

    package org.lytsing.android.log;
    
    import org.lytsing.android.util.Log;
    import android.app.Activity;
    import android.os.Bundle;
    
    public class LogDemo extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            Log.i("index=" + 3);
        }
    }

    运行结果的Log信息,如下图:

    需要的话,懒得复制粘贴,可以下载Log.java压缩文件包Log.tar.gz

    此外Android 代码风格指南 特别说明了,日志记录开销很大,应尽量少用,写规范可靠的代码,减少对debug的依赖。

  • 结婚祝福

    在问问上看到一个帖子:
    我有一个同窗3年的初中女同学今天结婚了,至今有10年没见,我想写一篇大概100来字文言文格式送给她,希望大家帮忙出点主意!

    特别要求:不要七绝五言诗歌格式的,要有“吾呼哀哉”的那种文言文,就是古文那种,大概100字左右

    问题补充  2009-11-28 15:36

    对了,我跟她10年没见了,她也没有请我们这些同学,只是知道她今天结婚了,而且我们上班也没时间参加她的婚礼,只是因为同窗情谊,想用祝福语来表达自己的心意。

    提问人的追问   2009-11-28 18:15您的回答实在是差矣差矣!求人不如求己,我自己研究了一个下午终于写出来了,发给你看看也无妨!

    今是己丑冬月十一,吾一同窗陈素阳之新婚吉日,特此赋文以纪之,其辞曰:

    悠悠寒日,恰逢素阳良辰美景。忆往昔十载之今日,吾等皆埋头于九重卷章之下,错此吉日,吾今唯有悔之好玩矣,致使今朝前程未知,仕途坎坷;念今时此刻,亦 相隔浩程几许,且不能前去与汝祝之,心甚憾矣!然“相知无远近,万里尚为邻。”彼虽遥离故友,千里为祈福:光照前程似锦,霞映继途如花;姿容益比今昔好, 才华更胜往日佳;结五湖四海亲朋好友,识六路八方英雄豪杰!三年七载,同窗恰似千秋水;十天九岁,友谊可比万代疆!一心之中莫存隙,二根以内不杂愁;佛 曰:烟花非你,你非烟花。往事无须悼,此生明媚,明朝烟云笑!小女子唯有恭贺新婚之禧!百事皆可乐!

  • 千万不要把Listview放在ScrollView里

    晚上逛了一下 eoe android论坛,见到一坨人千方百计的把ListView弄到ScrollView,还研究出一些策略,并引以为豪。eoe market也是用这样的设计,滚动条显示很诡异,时长时短。ListView 本来是不应该 放在 ScrollView 里的,Google员工 Roman Guy早已回复:“There is no need to put a ListView in a ScrollView since ListView already supports scrolling. Do NOT put a ListView inside a ScrollView. ListView already handles scrolling, you’re only going to run into trouble. “ 更详细的,大家可以看看他在 google i/o 上的ListView视频讲解。大家不要抱着侥幸的心理,要用正确的方法去做正确的事情。如果真的需要ListView不同行显示这样的设计,可以参考Mark Murphy提供的http://github.com/commonsguy/cwac-merge

  • ListView和Gallery实现Market首页界面(补充版)

    http://www.3gqa.com/?p=1941 可以看到沈青海老师的一段讲解视频。优酷的视频不是很清晰,可以在http://www.3gqa.com/?page_id=1307 页面按照提供的QQ登录网络硬盘下载高清版本。按视频动手写了一下,发现两个问题:
    1. 用滑鼠无法滚动到Galllery的图片
    2. 整个Galllery处于Selectable,很难看,如下图:
    andriod market gallery demo
    解决方法:
    1. 在ListView ,调用requestFocus方法还不够, 还需要setItemsCanFocus。
    2. 不让第0项处于可选中状态。
    public boolean areAllItemsEnabled() {
        return false;
    }
    
    public boolean isEnabled(int position) {
        return position != 0;
    }
    ListView功能强大,除了上面所用的方法,还可以用 addHeaderView 的方法把Gallery加进来,实现同样的效果。addHeaderView的使用,请参阅android reference 或Mark Murphy 在《The Busy Coder’s Guide To Advanced Android Development》书中提供的HeaderFooter 示例。