# 脚本库

## 概述

本文档收集了Android开发中常用的脚本，包括构建脚本、自动化脚本、工具脚本等。

## 构建脚本

### 1. Gradle构建脚本

#### 通用构建配置

```gradle
// build.gradle (Project)
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.2'
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}
```

#### 应用构建配置

```gradle
// build.gradle (App)
android {
    compileSdkVersion 33
    
    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode 1
        versionName "1.0.0"
    }
    
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
                    'proguard-rules.pro'
        }
    }
}
```

### 2. 构建优化脚本

```gradle
// 并行构建
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configureondemand=true

// 增加内存
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=512m
```

## 自动化脚本

### 1. 批量安装APK

```bash
#!/bin/bash
# install_apks.sh
# 批量安装当前目录下的所有APK

for apk in *.apk; do
    if [ -f "$apk" ]; then
        echo "Installing $apk..."
        adb install -r "$apk"
        if [ $? -eq 0 ]; then
            echo "Successfully installed $apk"
        else
            echo "Failed to install $apk"
        fi
    fi
done
```

### 2. 清理并重启

```bash
#!/bin/bash
# clean_and_reboot.sh
# 清理日志并重启设备

echo "Clearing logcat..."
adb logcat -c

echo "Clearing app data..."
adb shell pm clear com.example.app

echo "Rebooting device..."
adb reboot

echo "Waiting for device..."
adb wait-for-device

echo "Device is ready!"
```

### 3. 性能数据采集

```bash
#!/bin/bash
# collect_performance.sh
# 采集性能数据

OUTPUT_DIR="performance_data_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"

echo "Collecting CPU info..."
adb shell top -n 1 > "$OUTPUT_DIR/cpu.txt"

echo "Collecting memory info..."
adb shell dumpsys meminfo > "$OUTPUT_DIR/meminfo.txt"

echo "Collecting battery info..."
adb shell dumpsys batterystats > "$OUTPUT_DIR/batterystats.txt"

echo "Collecting network stats..."
adb shell dumpsys netstats > "$OUTPUT_DIR/netstats.txt"

echo "Data collected in $OUTPUT_DIR"
```

### 4. 日志收集脚本

```bash
#!/bin/bash
# collect_logs.sh
# 收集并过滤日志

PACKAGE_NAME="com.example.app"
OUTPUT_FILE="logs_$(date +%Y%m%d_%H%M%S).txt"

echo "Collecting logs for $PACKAGE_NAME..."
adb logcat | grep "$PACKAGE_NAME" > "$OUTPUT_FILE" &
LOGCAT_PID=$!

# 运行30秒
sleep 30

# 停止日志收集
kill $LOGCAT_PID

echo "Logs saved to $OUTPUT_FILE"
```

## ADB工具脚本

### 1. 设备管理脚本

```bash
#!/bin/bash
# device_manager.sh
# 设备管理工具

function list_devices() {
    echo "Connected devices:"
    adb devices -l
}

function get_device_info() {
    echo "Device Info:"
    echo "Model: $(adb shell getprop ro.product.model)"
    echo "Android Version: $(adb shell getprop ro.build.version.release)"
    echo "SDK Version: $(adb shell getprop ro.build.version.sdk)"
    echo "Manufacturer: $(adb shell getprop ro.product.manufacturer)"
}

function install_apk() {
    if [ -z "$1" ]; then
        echo "Usage: install_apk <apk_file>"
        return 1
    fi
    adb install -r "$1"
}

case "$1" in
    list)
        list_devices
        ;;
    info)
        get_device_info
        ;;
    install)
        install_apk "$2"
        ;;
    *)
        echo "Usage: $0 {list|info|install}"
        exit 1
        ;;
esac
```

### 2. 应用管理脚本

```bash
#!/bin/bash
# app_manager.sh
# 应用管理工具

PACKAGE_NAME="$2"

function stop_app() {
    adb shell am force-stop "$PACKAGE_NAME"
    echo "Stopped $PACKAGE_NAME"
}

function clear_data() {
    adb shell pm clear "$PACKAGE_NAME"
    echo "Cleared data for $PACKAGE_NAME"
}

function uninstall_app() {
    adb uninstall "$PACKAGE_NAME"
    echo "Uninstalled $PACKAGE_NAME"
}

function get_app_info() {
    adb shell dumpsys package "$PACKAGE_NAME" | grep -E "versionName|versionCode"
}

case "$1" in
    stop)
        stop_app
        ;;
    clear)
        clear_data
        ;;
    uninstall)
        uninstall_app
        ;;
    info)
        get_app_info
        ;;
    *)
        echo "Usage: $0 {stop|clear|uninstall|info} <package_name>"
        exit 1
        ;;
esac
```

## Python工具脚本

### 1. APK分析脚本

```python
#!/usr/bin/env python3
# apk_analyzer.py
# APK信息分析工具

import subprocess
import sys
import re

def get_apk_info(apk_path):
    """获取APK信息"""
    try:
        # 使用aapt获取信息
        result = subprocess.run(
            ['aapt', 'dump', 'badging', apk_path],
            capture_output=True,
            text=True
        )
        
        if result.returncode != 0:
            print(f"Error: {result.stderr}")
            return None
        
        info = {}
        for line in result.stdout.split('\n'):
            if 'package:' in line:
                # 解析包名和版本
                package_match = re.search(r"name='([^']+)'", line)
                version_match = re.search(r"versionCode='(\d+)'", line)
                version_name_match = re.search(r"versionName='([^']+)'", line)
                
                if package_match:
                    info['package'] = package_match.group(1)
                if version_match:
                    info['version_code'] = version_match.group(1)
                if version_name_match:
                    info['version_name'] = version_name_match.group(1)
            
            if 'application-label:' in line:
                label_match = re.search(r"label='([^']+)'", line)
                if label_match:
                    info['label'] = label_match.group(1)
        
        return info
    except Exception as e:
        print(f"Error: {e}")
        return None

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python apk_analyzer.py <apk_path>")
        sys.exit(1)
    
    apk_path = sys.argv[1]
    info = get_apk_info(apk_path)
    
    if info:
        print("APK Information:")
        for key, value in info.items():
            print(f"  {key}: {value}")
```

### 2. 日志分析脚本

```python
#!/usr/bin/env python3
# log_analyzer.py
# 日志分析工具

import re
import sys
from collections import Counter

def analyze_logs(log_file):
    """分析日志文件"""
    errors = []
    warnings = []
    patterns = {
        'crash': r'FATAL|crash|exception',
        'anr': r'ANR|Application Not Responding',
        'oom': r'OutOfMemory|OOM',
    }
    
    with open(log_file, 'r', encoding='utf-8', errors='ignore') as f:
        for line_num, line in enumerate(f, 1):
            # 检查错误
            if 'E/' in line or 'ERROR' in line.upper():
                errors.append((line_num, line.strip()))
            
            # 检查警告
            if 'W/' in line or 'WARN' in line.upper():
                warnings.append((line_num, line.strip()))
            
            # 检查特定模式
            for pattern_name, pattern in patterns.items():
                if re.search(pattern, line, re.IGNORECASE):
                    print(f"[{pattern_name.upper()}] Line {line_num}: {line.strip()}")
    
    print(f"\nSummary:")
    print(f"  Errors: {len(errors)}")
    print(f"  Warnings: {len(warnings)}")
    
    if errors:
        print(f"\nFirst 10 errors:")
        for line_num, line in errors[:10]:
            print(f"  Line {line_num}: {line}")

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python log_analyzer.py <log_file>")
        sys.exit(1)
    
    log_file = sys.argv[1]
    analyze_logs(log_file)
```

## Git工具脚本

### 1. 批量提交脚本

```bash
#!/bin/bash
# batch_commit.sh
# 批量提交更改

COMMIT_MESSAGE="$1"

if [ -z "$COMMIT_MESSAGE" ]; then
    echo "Usage: batch_commit.sh <commit_message>"
    exit 1
fi

# 添加所有更改
git add .

# 提交
git commit -m "$COMMIT_MESSAGE"

# 推送到远程
read -p "Push to remote? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
    git push
fi
```

### 2. 分支清理脚本

```bash
#!/bin/bash
# clean_branches.sh
# 清理已合并的分支

# 更新远程分支信息
git fetch --prune

# 切换到main分支
git checkout main
git pull

# 删除已合并的本地分支
git branch --merged | grep -v "\*\|main\|master" | xargs -n 1 git branch -d

# 删除远程已合并的分支
git remote prune origin

echo "Branches cleaned!"
```

## 性能测试脚本

### 1. 启动时间测试

```bash
#!/bin/bash
# test_startup_time.sh
# 测试应用启动时间

PACKAGE_NAME="com.example.app"
MAIN_ACTIVITY="com.example.app/.MainActivity"
ITERATIONS=10

echo "Testing startup time for $PACKAGE_NAME"
echo "Iterations: $ITERATIONS"
echo ""

total_time=0

for i in $(seq 1 $ITERATIONS); do
    # 停止应用
    adb shell am force-stop "$PACKAGE_NAME"
    sleep 1
    
    # 启动应用并测量时间
    result=$(adb shell am start -W -n "$MAIN_ACTIVITY" | grep "TotalTime")
    time=$(echo "$result" | awk '{print $2}')
    
    echo "Iteration $i: ${time}ms"
    total_time=$((total_time + time))
    
    sleep 2
done

average=$((total_time / ITERATIONS))
echo ""
echo "Average startup time: ${average}ms"
```

### 2. 内存监控脚本

```bash
#!/bin/bash
# monitor_memory.sh
# 监控应用内存使用

PACKAGE_NAME="$1"
INTERVAL=5

if [ -z "$PACKAGE_NAME" ]; then
    echo "Usage: monitor_memory.sh <package_name> [interval_seconds]"
    exit 1
fi

if [ -n "$2" ]; then
    INTERVAL="$2"
fi

echo "Monitoring memory for $PACKAGE_NAME (interval: ${INTERVAL}s)"
echo "Press Ctrl+C to stop"
echo ""

while true; do
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    meminfo=$(adb shell dumpsys meminfo "$PACKAGE_NAME" | grep "TOTAL")
    
    if [ -n "$meminfo" ]; then
        pss=$(echo "$meminfo" | awk '{print $2}')
        echo "[$timestamp] PSS: ${pss}KB"
    fi
    
    sleep "$INTERVAL"
done
```

## 部署脚本

### 1. 自动部署脚本

```bash
#!/bin/bash
# deploy.sh
# 自动构建和部署

echo "Building APK..."
./gradlew assembleRelease

if [ $? -ne 0 ]; then
    echo "Build failed!"
    exit 1
fi

APK_PATH="app/build/outputs/apk/release/app-release.apk"

if [ ! -f "$APK_PATH" ]; then
    echo "APK not found: $APK_PATH"
    exit 1
fi

echo "Installing APK..."
adb install -r "$APK_PATH"

if [ $? -eq 0 ]; then
    echo "Deployment successful!"
else
    echo "Deployment failed!"
    exit 1
fi
```

## 使用说明

### 脚本执行权限

```bash
# 添加执行权限
chmod +x script.sh

# 执行脚本
./script.sh
```

### 脚本路径

建议将常用脚本放在 `~/scripts/` 目录下，并添加到PATH：

```bash
# 添加到 ~/.bashrc 或 ~/.zshrc
export PATH="$HOME/scripts:$PATH"
```

## 相关链接

- [[效率工具推荐/README]]
- [[09-调试与工具链/ADB高级命令]]
