いまさら再導入 peco for mac (2)
exception-think.hatenablog.com の続き
- gradleコマンド補完スクリプト(pgradle.sh)
- apkの逆アセンブル用スクリプト(apkd.sh)
- apkの取り置き用スクリプト(apkc.sh)
- gradlew のタスク終了シェル(jkill.sh)
- アプリのデータ消去&run-apk(pclear.sh)
- SqliteDbの初期化(pdeldb.sh)
- adb forwardのブリッジ(TelnetSqliteを使うにあってたっての)<padbf.sh>
- genymotion Gappsインストールスクリプト(adbpush.sh)
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のフォルダ直下に
- apktool
- dex2jar
なお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 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 rem ★d2j-dex2jarは古いため、最近はAndroidManifest.xmlを正常に解凍できないためバックアップをとっておく mv out/%%~ni/AndroidManifest.xml out/%%~ni/AndroidManifest_mst.xml 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 cp -f $TARGET_APK out # ★d2j-dex2jarは古いため、最近はAndroidManifest.xmlを正常に解凍できないためバックアップをとっておく cp out/$FNAME/AndroidManifest.xml out/$FNAME/AndroidManifest_mst.xml 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
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 Studio と android 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%