いまさら再導入 peco for mac (2)

exception-think.hatenablog.com の続き


gradleコマンド補完スクリプト(pgradle.sh)

  • PROJECT_ROOT/build.gralde
allprojects {

    //-XlintのワーニングをASのMessageタブに表示させる
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
        }
    }
    
    //pgradle.sh/pgradle.bat用
    //こう書かないとFlavorとか使っている場合 gradlew tasks で一覧に表示されない
    task build_tasks << {
    def list = []
    tasks.findAll{it.group == "build"}.unique(false){it.name}.each{task->
        list.add(task.name);
    }
    list.unique(true).each{
        println(it)
    }
    }

    tasks.whenTaskAdded { task ->
        //=>Test系のタスクは向こうにしてみる(毎回ビルド時に勝手に動いているので)
        if (task.name.indexOf("Test")!=-1) {
            task.enabled = false
        }

        if (task.name.indexOf("assemble")!=-1) {
            task.group = "build"
        }
    if (task.name.indexOf("crashlytics")!=-1) {
        task.group = "build"
    }
    if (task.name.indexOf("clean")!=-1) {
        task.group = "build"
    }
    }
}
  • pgradle.sh
#!/bin/sh

if [$1 = '']; then
    PECO_CMD=peco
else
    PECO_CMD="peco --query $1"
fi

# product flavorを使っていなければ「gradlew tasks」でもOK
SELECT_CMD=`gradlew build_tasks --offline | $PECO_CMD |awk '{print $1}'`

echo gradlew $SELECT_CMD
gradlew $SELECT_CMD --offline

apkの逆アセンブルスクリプト(apkd.sh)

巷で大人気の AS2.2 のApkAnalizer がございますが、これdebug.apkにしか使えないんじゃないかと。

で実際知りたいのはrelease.apkとdexする時のproguadの除外とか効いているかどうか

release用のapkで動作確認とかしているときに

ClassNotFoundException

とか出始めるとね。。大騒ぎになるわけで

事前設定編

pecoのフォルダ直下に

なおdex2jarに関しては

解凍後のdex2jar-2.0フォルダのshに実行権限を付与しておくこと

chmod a+x *.sh

書き換え編

パスからファイル名を取得するというと

に記載されているように

DOS bash 機能
%~i $TARGET_APK フルパス
%~nxi FNAME_EXT=“${TARGET_APK##*/}” ファイル名と拡張子
%~ni FNAME=“${FNAME_EXT%.*}” ファイル名のみ
%~xi EXT=“${FNAME_EXT##*.}"|拡張子のみ

となりますので、これをもとに置き換えてみます

  • apkd.bat
@echo off
set PECO_HOME=C:/soft/peco
set APKTOOL_HOME=%PECO_HOME%
set DEX2JAR_HOME=%PECO_HOME%/dex2jar-2.0

@echo off
for /f %%i in ('dir /s /b *.apk ^| peco') do (
    echo apk file %%i
    java -jar %APKTOOL_HOME%/apktool_2.2.0.jar d %%i -o out/%%~ni
    cp %%i out
    unzip -d out/%%~ni out/%%~nxi
    %DEX2JAR_HOME%/d2j-dex2jar.bat out/%%~ni/classes.dex -o out/%%~ni/classes-dex2jar.jar
)

=>

  • apkd.sh
#!/bin/sh

PECO_HOME=$HOME/Documents/soft/peco
APKTOOL_HOME=$PECO_HOME
DEX2JAR_HOME=$PECO_HOME/dex2jar-2.0

TARGET_APK=`find . -iname "*.apk" -type f | peco --select-1`
if [$TARGET_APK = '']; then
    exit
fi

FNAME_EXT="${TARGET_APK##*/}"
FNAME="${FNAME_EXT%.*}"
EXT="${FNAME_EXT##*.}"

echo apk file $FNAME_EXT
mkdir out

java -jar $APKTOOL_HOME/apktool_2.2.0.jar d $TARGET_APK -o out/$FNAME -f

# ★d2j-dex2jarは古いため、最近はAndroidManifest.xmlを正常に解凍できないためバックアップをとっておく
cp out/$FNAME/AndroidManifest.xml out/$FNAME/AndroidManifest.xml_bak


cp -f $TARGET_APK out
unzip -d out/$FNAME out/$FNAME_EXT
$DEX2JAR_HOME/d2j-dex2jar.sh out/$FNAME/classes.dex -o out/$FNAME/classes-dex2jar.jar --force

apktoolsで逆アセンブルした classes-dex2jar.jar まで開くのであれば

open -a JD-GUI out/$FNAME/classes-dex2jar.jar 

を追記する


apkの取り置き用スクリプト(apkc.sh)

  • InstantRun
  • なんかよくわからないエラー出たらclean buildしようぜ

とかいうAS記事が結構おおくて、動いていたときのapkとか消されちゃうことが多い。

  • timestampを YYYYMMDD_HHMMSS に修正してファイルに付加 の方針で

単に現在時間だけなら

CURRENT_TIME=date +%s で十分では有るんだけど。。

  • apkc.sh
#!/bin/sh

TARGET_APK=`find . -iname "*.apk" -type f | peco --select-1`
if [$TARGET_APK = '']; then
    exit
fi

TIMESTAMP=`stat -f %m $TARGET_APK`
TIMESTAMP=`date -r $TIMESTAMP +"%Y%m%d_%H%M%S"`

FNAME_EXT="${TARGET_APK##*/}"
FNAME="${FNAME_EXT%.*}"
EXT="${FNAME_EXT##*.}"

FNAME_NEW=out/${FNAME}_${TIMESTAMP}.${EXT}

echo "ORIGIN_FILE:"$TARGET_APK
echo "NEW_FILE   :"$FNAME_NEW

mkdir out
cp -pf $TARGET_APK $FNAME_NEW

macじゃないunix系だと、通常は

stat -c “%Y” $TARGET_APK になるらしい。


gradlew のタスク終了シェル(jkill.sh)

gradlewが暴走した時

QittaでASのterminalから

gradlew –stop

だけで万事解決とか書いてる記事を読んだことが有りますが、実はあれで停止できないことがよくある。

あれって昔のshellとかで実行中の中間ファイルの有無で daemonの存在有無見てるだけじゃないかなーというのが感想。

まあjpsコマンドにしても、java経由のpid情報ファイルを見ているだけなんですけどね*1

  • jkill.bat
echo off
for /f "tokens=1" %%A in ('jps -lv ^| findstr -v "AppMain" ^| findstr -v "AndroidStudio"^| findstr -v "IntelliJIdea" ') do (taskkill /F /PID %%A)

=>

  • jkill.sh
#!/bin/sh

kill -9 `jps -lv | grep -v AppMain | grep -v "AndroidStudio" | grep -v "IntelliJIdea" | grep -v "sdkmanager" | awk '{print $1}'`

Android Studioandroid sdk manager と IDEAを除く設定。


アプリのデータ消去&run-apk(pclear.sh)

#!/bin/sh

TARGET_APK=`find . -iname "*.apk" -type f | peco --select-1`
if [$TARGET_APK = '']; then
    exit
fi

DEVICE=`adb devices -l |grep -v attached |grep -v daemon |peco --select-1|awk '{print $1}'`
if [$DEVICE = '']; then
    exit
fi

PACKAGE=$(aapt dump badging $TARGET_APK|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
ACTIVITY=$(aapt dump badging $TARGET_APK|awk -F" " '/launchable-activity/ {print $2}'|awk -F"'" '/name=/ {print $2}')

OS_VER=`adb -$DEVICE shell getprop ro.build.version.release`


echo "PACKAGE:"$PACKAGE
echo "DEVICE :"$DEVICE
echo "OS_VER :"$OS_VER

#pm-clear
adb -s $DEVICE shell pm clear $PACKAGE

#run-apk
adb -s $DEVICE shell am start -n $PACKAGE/$ACTIVITY --activity-clear-top

まあ実質的な話として、pm clear してしまうと

アプリが終了してしまうので再起動は必要

6系のRequestPermission情報も、アプリケーションデータとして保存されているので

pm clearで初期化が可能だったりします


SqliteDbの初期化(pdeldb.sh)

#!/bin/sh

DBNAME=hoge.db

TARGET_APK=`find . -iname "*.apk" -type f | peco --select-1`
if [$TARGET_APK = '']; then
    exit
fi

DEVICE=`adb devices -l |grep -v attached |grep -v daemon |peco --select-1|awk '{print $1}'`
if [$DEVICE = '']; then
    exit
fi

PACKAGE=$(aapt dump badging $TARGET_APK|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
OS_VER=`adb -$DEVICE shell getprop ro.build.version.release`


echo "PACKAGE:"$PACKAGE
echo "DEVICE :"$DEVICE
echo "OS_VER :"$OS_VER

# DB削除
adb -s $DEVICE shell "run-as $PACKAGE rm /data/data/${PACKAGE}/databases/${DBNAME}"
adb -s $DEVICE shell "run-as $PACKAGE rm /data/data/${PACKAGE}/databases/${DBNAME}-journal"

まあ理想を言えば

adb -s $DEVICE shell “run-as $PACKAGE rm /data/data/${PACKAGE}/databases/.

なんですけど、たしか上手く動かなかったような記憶があり(あとで再検証する予定)


adb forwardのブリッジ(TelnetSqliteを使うにあってたっての)<padbf.sh>

詳細は下記の話。でもまあ 時代は Realm らしいので使う人少ないかも。。

exception-think.hatenablog.com

#!/bin/sh

DEVICE=`adb devices -l |grep -v attached |grep -v daemon |peco --select-1|awk '{print $1}'`
if [$DEVICE = '']; then
    exit
fi

OS_VER=`adb -$DEVICE shell getprop ro.build.version.release`


echo "DEVICE :"$DEVICE
echo "OS_VER :"$OS_VER

adb -s $DEVICE shell forward tcp:12080 tcp:12080

genymotion Gappsインストールスクリプト(adbpush.sh)

以前は [#]でコメントされた奴を記述していたんですが、

  • zip選択が結構面倒
    • でかいzipは公式推奨のD&Dで入れるとPlayer自体が応答なしになる
  • genymotion player の 192.168.57. X のipが起動する度に変わる

あたりでpeco対応に修正しています

  • adbpush.sh
#!/bin/sh

#TARGET_ZIP=`basename $1`
TARGET_ZIP=`find . -iname "*.zip" -type f | peco --select-1`
if [$TARGET_ZIP = '']; then
    exit
fi


#DEVICE=192.168.57.101:5555
DEVICE=`adb devices -l | grep 192.168.57. |peco --select-1|awk '{print $1}'`
if [$DEVICE = '']; then
    exit
fi

adb -s $DEVICE push $TARGET_ZIP /sdcard/Download/
adb -s $DEVICE shell /system/bin/flash-archive.sh /sdcard/Download/$TARGET_ZIP
adb -s $DEVICE shell rm /sdcard/Download/$TARGET_ZIP
  • adbpush.bat
rem see http://tooljp.com/bat_qa/18600DE33DE3E5FD49257378005A0CB5.html
set TARGET_NAME=%~nx1 
set TARGET_DEVICE=192.168.57.101:5555
adb -s %TARGET_DEVICE% push %TARGET_NAME% /sdcard/Download/
adb -s %TARGET_DEVICE% shell /system/bin/flash-archive.sh /sdcard/Download/%TARGET_NAME%
adb -s %TARGET_DEVICE% shell rm /sdcard/Download/%TARGET_NAME%

*1:jpsが動かなくなったときの復旧手段が未だにわかんないし。。