Android内存压力测试工具(memtester移植)

2023-10-29

该文章转载于:

android用memtester内存压力测试_W歹匕示申W的博客-CSDN博客

Android内存压力测试工具(memtester移植)_甜牛奶蛋糕的博客-CSDN博客_android 内存压力测试

DRR参考配置OK之后,首先需要的是对DDR进行压力测试保证DDR的稳定性,否则DDR出问题之后,很容易引起奇奇怪怪的问题,很难分析问题原因

memtester说明:

memtester主要用于测试内存稳定性
官网:https://pyropus.ca./software/memtester/old-versions/
版本:memtester-4.3.0.tar.gz(目前最新版本-2018.10.21)
官方已经预编译了大部分Linux系统的二进制文件,可以直接使用,现在我们将它移植到Android系统中。

移植

首先我们看看Makefile文件它在Linux系统是怎么编译的,这里移植memtester-4.3.0.tar.gz压缩包里的文件不需要任何修改。

memtester: \
$(OBJECTS) memtester.c tests.h tests.c tests.h conf-cc Makefile load extra-libs
	./load memtester tests.o `cat extra-libs`

从上面的Makefile可以知道,要编译memtester需要编译memtester.c和tests.c以及相关的头文件,所以我们可以写出下面的Android.mk文件。

​LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := memtester.c tests.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_MODULE := memtester
include $(BUILD_EXECUTABLE)

memtester-4.3.0.tar.gz解压到system/core/目录下,并命名为memtester目录,并把Android.mk放到同一目录。文件如下显示。

~/project$ tar -zxvf memtester-4.3.0.tar.gz -C AndroidO_8827LGO_20181207/system/core/
~/project$ cd AndroidO_8827LGO_20181207/system/core/memtester
~/project/AndroidO_8827LGO_20181207/system/core/memtester$tree
.
├── Android.mk
├── BUGS
├── CHANGELOG
├── conf-cc
├── conf-ld
├── COPYING
├── extra-libs.sh
├── find-systype.sh
├── make-compile.sh
├── Makefile
├── make-load.sh
├── make-makelib.sh
├── memtester.8
├── memtester.c
├── memtester.h
├── README
├── README.tests
├── sizes.h
├── tests.c
├── tests.h
├── trycpp.c
├── types.h
└── warn-auto.sh

先编译成模块进行测试:

~/project/AndroidO_8827LGO_20181207/system/core/memtester$ mm -j8
........
5 warnings generated.
[100% 6/6] Install: out/target/product/petrel-p1/system/bin/memtester
make: Leaving directory '/home/lemon/Develop/OrangePi_Lite2/android'


#### make completed successfully ####

然后就可以通过

adb push memtester /system/bin/
adb shell "chmod 777 /system/bin/memtester"
adb shell memtester 

最后添加到device.mk中,系统全编译时打包到系统,所以还需要在device.mk里面进行定义

PRODUCT_PACKAGES += memtester

测试

使用方法:Usage: memtester [-p physaddrbase [-d device]] [B|K|M|G] [loops],比如memtester 5M 1,对应测试1次5M内存

PS C:\Users\zhaojr\Documents\adb> ./adb root
adbd is already running as root
PS C:\Users\zhaojr\Documents\adb> ./adb remount
remount succeeded
PS C:\Users\zhaojr\Documents\adb> ./adb shell
8227LGO_demo:/ # memtester                                                                                                                               
memtester version 4.3.0 (32-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffff000
need memory argument, in MB

Usage: memtester [-p physaddrbase [-d device]] <mem>[B|K|M|G] [loops]

查看系统空闲内存,还有251M

8227LGO_demo:/ # free -h
free -h
                total        used        free      shared     buffers
Mem:             443M        432M         11M        328K        576K
-/+ buffers/cache:           431M         12M
Swap:            329M         73M        256M
8227LGO_demo:/ #

演示:memtester 5M 1,这里只是演示,测试1次5M内存,实际项目中这两个参数应尽可能大,才能覆盖整块内存,才能达到压力测试的结果,测试时失败有相应的log,我这里比较难复现就不贴了。

8227LGO_demo:/ # memtester 5M 1                                                                                                                          
memtester version 4.3.0 (32-bit)
Copyright (C) 2001-2012 Charles Cazabon.
Licensed under the GNU General Public License version 2 (only).

pagesize is 4096
pagesizemask is 0xfffff000
want 5MB (5242880 bytes)
got 5MB (5242880 bytes), trying mlock ...locked.
Loop 1/1:
  Stuck Address : ok         
  Random Value : ok
  Compare XOR : ok
  Compare SUB : ok
  Compare MUL : ok
  Compare DIV : ok
  Compare OR : ok
  Compare AND : ok
  Sequential Increment: ok
  Solid Bits : ok         
  Block Sequential : ok         
  Checkerboard : ok         
  Bit Spread : ok         
  Bit Flip : ok         
  Walking Ones : ok         
  Walking Zeroes : ok         

Done.
8227LGO_demo:/ #

Android APK的应用

主文件:
package com.example.ddr;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class MainActivity extends Activity {
private static final String TAG = null;
private static TextView test_result = null;
static String test_setText = "";
static int Testing_times = 0;
String asdddd1 = "screencap -p /sdcard/screen1.png";
String asdddd2 = "screencap -p /sdcard/screen2.png";
String dir = "/data/data/com.example.ddr/files/";  
Context ctxDealFile = null;
String oldPath1 = "file:///android_asset/memtester";
String oldPath2 = "file:///memtester";
String newPath1 = Environment.getRootDirectory().getPath();//"system/";//"system/bin/";
String MemtesterFileName = "/data/memtester_result.txt";
String simpleMemtester_1 = "memtester -b -g -f 1190400--1190400 64M 1";
String complexMemtester_1 = "memtester -b -j 0 -k 4 -g -l 40 -a 64M";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        test_result = (TextView)findViewById(R.id.Memtester_01);
        System.out.println("csh ddr star");
        Memtester(simpleMemtester_1);
        Memtester(complexMemtester_1);
        //ReadTxtFile(MemtesterFileName);
        //copyFile(oldPath2,newPath1);
        /*String uiFileName = "memtester";
        
try {
ctxDealFile = this.createPackageContext("com.example.ddr",
Context.CONTEXT_IGNORE_SECURITY);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}        
deepFile(ctxDealFile, uiFileName);*/
    }
    public void deepFile(Context ctxDealFile, String path) {
try {
String str[] = ctxDealFile.getAssets().list(path);
if (str.length > 0) {
System.out.println("csh deepFile 1");
File file = new File("/system/" + path);
file.mkdirs();
for (String string : str) {
path = path + "/" + string;
System.out.println("zhoulc:\t" + path);
// textView.setText(textView.getText()+"\t"+path+"\t");
deepFile(ctxDealFile, path);
path = path.substring(0, path.lastIndexOf('/'));
}
} else {
System.out.println("csh deepFile 2");
InputStream is = ctxDealFile.getAssets().open(path);
//FileOutputStream fos = new FileOutputStream(new File(getFilesDir().getAbsolutePath()+"/memtester"));
FileOutputStream fos = ctxDealFile.openFileOutput(path, 
ctxDealFile.MODE_WORLD_READABLE |ctxDealFile.MODE_WORLD_WRITEABLE);
byte[] buffer = new byte[1024];
int count = 0;
while (true) {
count++;
int len = is.read(buffer);
if (len == -1) {
break;
}
fos.write(buffer, 0, len);
}
is.close();
fos.close();

}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Process p;
Process p2;
try {
p = Runtime.getRuntime().exec("chmod 777 " + dir + path);
p.waitFor();
p2 = Runtime.getRuntime().exec("cp /data/data/com.example.ddr/files/memtester > /data/data/com.example.ddr/files/memtester2");
p2.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    }
    public void  Memtester(String command)
    {
        Runtime r = Runtime.getRuntime();
        Process p;
        Testing_times ++;
            try {
                p = r.exec(command);
                BufferedReader br = new BufferedReader(new InputStreamReader(p
                        .getInputStream()));
                String inline;
                while ((inline = br.readLine()) != null) {
                    System.out.println(inline);
                }
                br.close();
p.waitFor();
ReadTxtFile(MemtesterFileName);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
    }
    /*public void  Memtester2(String command)
    {
    DataOutputStream os = null;
    Process p;
    try{
    p =Runtime.getRuntime().exec(isRoot?COMMAND_SU:COMMAND_SH);
    os = new DataOutputStream(p.getOutputStream());
    for (String command:commands){
    if(command==null){
    continue;
    }


    //donnotuseos.writeBytes(commmand),avoidchinesecharseterror
    os.write(command.getBytes());
    os.writeBytes(COMMAND_LINE_END);
    os.flush();


    try{
    }catch(Exception e){
    e.printStackTrace();
    }
    }*/
    public static String ReadTxtFile(String strFilePath)
    {
        String path = strFilePath;
        String content = "";
            File file = new File(path);
            if (file.isDirectory())
            {
                Log.d("TestFile", "The File doesn't not exist.");
            }
            else
            {
                try {
                    InputStream instream = new FileInputStream(file); 
                    if (instream != null) 
                    {
                        InputStreamReader inputreader = new InputStreamReader(instream);
                        BufferedReader buffreader = new BufferedReader(inputreader);
                        String line;
                        while (( line = buffreader.readLine()) != null) {
                            content += line + "\n";
                            //if(inline.equals("SUCCESS")){
                            if(line.indexOf("SUCCESS")!=-1){
                            test_setText += Testing_times + " : " + "SUCCESS \n";
                            test_result.setText(test_setText);
                            }else{
                            test_setText += Testing_times + " : " + "FAIL \n";
                            test_result.setText(test_setText);
                            }
                        }                
                        instream.close();
                    }
                }
                catch (java.io.FileNotFoundException e) 
                {
                    Log.d("TestFile", "The File doesn't not exist.");
                } 
                catch (IOException e) 
                {
                     Log.d("TestFile", e.getMessage());
                }
            }
            return content;
    }    


    /*
    private void simpleMemtester(){
    Log.d(TAG, "do simple memory test");
    openCmdList1.clear();
    try {
    openCmdList1.add("memtester -b -g -f 1190400--1190400 64M 1");
    exec(openCmdList1);
    memoryTestResult();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    private void complexMemtester(){
    Log.d(TAG, "do complex memory test");
    openCmdList1.clear();
    try {
    openCmdList1.add("memtester -b -j 0 -k 4 -g -l 40 -a 64M");
    exec(openCmdList1);
    memoryTestResult();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    
    */


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

APK预置到代码里面给个系统权限:

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SDK_VERSION := current
LOCAL_PACKAGE_NAME := ddr
include $(BUILD_PACKAGE)
# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))

配置文件配置手机UID权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.memtester_ckt"
    android:versionCode="1"
    android:versionName="1.0"
android:sharedUserId="android.uid.system">

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

把文件用android代码预置到手机system/bin下面,也就给手机配置了脚本环境:

CSH_DDR_PATH := packages/apps/ddr/assets
PRODUCT_COPY_FILES := $(CSH_DDR_PATH)/memtester:system/bin/memtester $(PRODUCT_COPY_FILES)

linux嵌入式环境下的使用:

#!/bin/sh

# Memory Tester Scripts
# by KaKa
# version = date
VERSION="Fri Oct 19 11:56:57 CST 2007"
# trap for irruptions
MEMTESTER=${PWD}/memtester
PPIDKILL=$$
SIDKILL=$$
trap "pkill -9 -P ${PPIDKILL};kill -9 $$" INT
trap "pkill -9 -P ${PPIDKILL};kill -9 $$" KILL
cat <<-EOF_vpps >&2
Version: ${VERSION}
PID: $$
PPIDKILL: ${PPIDKILL}
SIDKILL: ${PPIDKILL}
EOF_vpps
CORE_NUM=$(grep -i ^processor /proc/cpuinfo|wc -l)
MEMTESTERCOPY=${CORE_NUM}
MEM_TOTAL_K=$(awk '/^MemTotal/{print $2}'  /proc/meminfo)
MEM_RESERVE_PERCENTAGE=$((1000*50/1024))
MEM_RESERVED=$((MEM_TOTAL_K/1024*MEM_RESERVE_PERCENTAGE/1000))
MEM_TOTAL_TOBETESTED=$((MEM_TOTAL_K/1024-MEM_RESERVED))
MEM_PER_COPY=$((MEM_TOTAL_TOBETESTED/MEMTESTERCOPY))
RUN_DURATION_TIME=0
RUN_LOOPS=-1
RUN_DURATION_TIME_FLAG=0
RUN_LOOPS_FLAG=0
DDPERCOPY_TIME=6s
LOGDIR=/tmp/memtester-log-${$}
mkdir -p ${LOGDIR}

show_help () {
    cat <<HELPEOF >&2
    Version: ${VERSION}
    Usage: $(basename ${0})
    -r Directory: the root location of memtester binary file
    -c NUMBER: the copies of memtester should be run
    -m NUMBER: how many memory should be tested totally (in MB)
    -t TIME:   duration mode, how long will the tests go
    -l NUMBER: loops mode,how many loops will each memtester should go
    The option -t and -l are exclusive, which means tests could work
    only with   1. duration mode or 2. loops mode
    RUN 4 copies memtester with in 24 hours, to test total 4000 MB memory:
        $(basename ${0}) -t 24h -c 4 -m 4000
    RUN 2 copies memtester with in 1 hours, to test total 4000 MB memory:
        $(basename ${0}) -t 1h -c 4 -m 4000
    RUN 4 copies memtester with in 2 loops, to test total 3600 MB memory:
        $(basename ${0}) -l 2 -c 4 -m 3600
    -V/-h/-H: show this info.
HELPEOF
    exit 0
}

while getopts :c:m:t:l:r:p:hHVvx OPTION
do
    case ${OPTION} in
    c)
        #echo "-c ${OPTARG}"
        MEMTESTERCOPY=${OPTARG}
    ;;
    m)
        #echo "-m ${OPTARG} MB"
        MEM_TOTAL_TOBETESTED=${OPTARG}
        MEM_RESERVED=$((MEM_TOTAL_K/1024-MEM_TOTAL_TOBETESTED))
    ;;
    t)
        #echo "-t ${OPTARG}"
        [ 0 -ne ${RUN_LOOPS_FLAG} ] && echo "-t and -l are exclusive." && exit 222
        RUN_DURATION_TIME=${OPTARG}
        RUN_DURATION_TIME_FLAG=1
    ;;
    l)
        #echo "-l ${OPTARG}"
        [ 0 -ne ${RUN_DURATION_TIME_FLAG} ] && echo && echo "-t and -l are exclusive." && show_help && echo && exit 223
        RUN_LOOPS=${OPTARG};
        RUN_LOOPS_FLAG=1
    ;;
    d)
        #echo "-r ${OPTARG}"
        MEMTESTER=${OPTARG}/memtester
    ;;
    p)
        #echo "-p ${OPTARG}"
        MEMTESTER=${OPTARG}
    ;;
    V|h|H)
        show_help
    ;;
    v)
        set -v
    ;;
    x)
        set -x
    ;;
    ?)
        echo "Error...";
        echo "?Unknown args..."
        exit 224
    ;;
    *)
        #echo "*Unknown args..."
    esac
done
    #exit
[ 0 -eq ${RUN_DURATION_TIME_FLAG} ] && [ 0 -eq ${RUN_LOOPS_FLAG} ] &&
echo && echo "Please specified which mode should we run... -t or -l" &&
show_help && echo && exit 225
MEM_PER_COPY=$((MEM_TOTAL_TOBETESTED/MEMTESTERCOPY))
    echo "Mem total: " $((MEM_TOTAL_K/1024)) MB
    echo "Core total: "${CORE_NUM}
    echo "Memtester copys: " ${MEMTESTERCOPY}
    echo "Mem per copy: "${MEM_PER_COPY}
    echo "Mem total to used: "${MEM_TOTAL_TOBETESTED} MB
    if [ ${MEM_RESERVED} -lt 1 ]; then
        echo "Mem reserved: -- No more memory reserved..."
    else 
        echo "Mem reserved: "${MEM_RESERVED} MB
    fi
    #exit
    # GOGOGO
    if [ 0 -ne ${RUN_DURATION_TIME_FLAG} ]; then
        echo "Run within a duration: ${RUN_DURATION_TIME}"
    elif [ 0 -ne ${RUN_LOOPS_FLAG} ]; then
        echo "Run within a loop: ${RUN_LOOPS}"
    fi

    echo "Working directory: " $PWD
    echo "Memtester: " ${MEMTESTER}
    echo "LOGs directory: " $LOGDIR
    echo
    echo -n "Jobs started at date: "
    date #+%Y/%m/%d\ %H:%M
    echo
    #exit
########################
# Run testing within a duration time.
    if [ 0 -ne ${RUN_DURATION_TIME_FLAG} ]; then
    # prepareing the sleeping killers
        sleep ${RUN_DURATION_TIME}
        echo -n "End of testing(TIMEOUT)... "
        echo "KILL CHILD" && kill -9 $(pgrep -P ${PPIDKILL} memtester) && echo
        "Childen processes - KILLED."
        # attention to how the memtesters are forked...
        echo "KILL PARENT" && kill $$  && echo "KILLED." &
        echo "Finished the memtester"
        echo -n "Jobs finished at date: "
        date #+%Y/%m/%d\ %H:%M
    fi &
    echo -n "Waiting (PID: $$) for ${MEMTESTERCOPY}
    memtesters(${MEM_PER_COPY}MB for each). "
    if [ 0 -ne ${RUN_DURATION_TIME_FLAG} ]; then
        echo -n "For time: ${RUN_DURATION_TIME} "
    fi

    if [ 0 -ne ${RUN_LOOPS_FLAG} ]; then
        echo -n "For loops: ${RUN_LOOPS} "
    fi
    echo "..."
    while true
    do
        MEMTESTER_NUM=0
        echo -n "{"
        while [ ${MEMTESTER_NUM} -lt ${MEMTESTERCOPY} ]
        do
            echo -n " ${MEMTESTER_NUM} "
            if [ 0 -ne ${RUN_DURATION_TIME_FLAG} ]; then
                RUN_LOOPS=0
            fi
            ${MEMTESTER} ${MEM_PER_COPY} ${RUN_LOOPS} 2>&1 >> ${LOGDIR}/${MEMTESTER_NUM}.log &
    # set loops = 0 to make memtester run loop infinitely...
    # .pogo version will run only one loop by default
            sleep ${DDPERCOPY_TIME}
            MEMTESTER_NUM=$(expr $MEMTESTER_NUM + 1)
        done
        echo -n "}"
        wait
        [ 0 -ne ${RUN_LOOPS_FLAG} ] && break
        # memtesters' loops...
   done
########################
echo
echo -n "End of testing(Excution ended)... "
pkill -9 -P ${PPIDKILL}
kill $$
echo "Finished the memtester"
echo -n "Jobs finished at date: "
date #+%Y/%m/%d\ %H:%M

运行这个脚本:

sh memory.sh -c <number> -l <number> -m <memory>

-c:运行几个memtester

-l:运行几次

-m:测试多大的内存,直接填测试总数即可,程序会自动分配个平均值给每个memtester,这样省去我们自己的计算,也不用多开几个终端了,单位MB,例如我有一个四核CPU,32G 内存的机器,就可以这样运行:

sh memory.sh -c 4 -l 1 -m 3100

大家可以看这个脚本中还可以限定时间,例如我想运行24个小时

sh memory.sh -t 24h -c 4 -m 3100
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android内存压力测试工具(memtester移植) 的相关文章

  • Android 在打开应用程序时会广播吗?

    例如 如果我想知道Youtube何时打开 是否有与之相关的广播 我当然知道我可以轮询 logcat 消息来检查活动 但我可以通过广播来做到这一点吗 因为它会少得多的耗电 此链接似乎表明这是不可能的 如何跟踪 Android 中的应用程序使用
  • Manifest Merger工具:替换失败

    我正在使用一个使用自己的 android theme 的库 因此在构建时收到以下错误 错误 55 9 任务 contacit processDebugManifest 执行失败 清单合并失败 AndroidManifest xml 中的属性
  • Service 和 IntentService,运行从服务器轮询数据库值的服务哪个更好?

    我读过很多关于Service and IntentService 然而 当做出决定时 我没有足够的信心选择使用哪种类型来创建一个后台服务 该服务将在一定时间间隔内从数据库轮询数据 并在获得所需数据时停止它 因为数据代表请求的状态 例如 订购
  • Android 如何更改 OnTouchListener 上的按钮背景

    你好 我在 xml 中有一个按钮 我正在使用OnTouchListener在我的活动中获得button按下并释放 但问题是 当我按下按钮时背景颜色没有改变 当我延长可能的活动时OnClickListener背景正在改变 任何人都可以告诉我的
  • ffmpeg视频已压缩但无法在浏览器中播放

    我已经集成了ffmpeg4android lib 视频压缩工作正常 但视频无法在除 safari 浏览器之外的浏览器中播放 上传到服务器后 我使用了以下命令 ffmpeg y i
  • 调试:在 Android 1.0 中找不到文件

    今天我更新到 Android Studio v 1 0 在尝试编译任何项目时出现以下错误 app build intermediates classes debug 找不到文件 问题是在更新之前我没有任何问题 这是我实际尝试编译的代码 构建
  • 如何在android线性布局上获得阴影? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在android中为View设置阴影 https stackoverflow com questions 4406524 how to set shadow to a view in androi
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • AudioTrack、SoundPool 或 MediaPlayer,我应该使用哪个?

    如果我需要能够 播放多个音频文件 具有不同的持续时间 例如 5 到 30 秒 独立设置右 左声道的音量 应用声音效果 如混响 失真 那么 我应该使用哪个 API 另外 我在 AudioTrack API 上找不到太多文档 有谁知道在哪里可以
  • Android 服务是否有办法检测设备何时锁定?

    我有一个 Android 服务 我希望在设备锁定时执行操作 我想澄清一下 我对屏幕开 关状态不感兴趣 我知道如何使用带有 Intent ACTION USER PRESENT 和 KeyguardManager inKeyguardRest
  • glTexImage2D: 之前出错:( 0x506 内部 0x1908 格式 0x1908 类型 0x1401

    当使用 Android Studio 运行模拟器时 我在模拟器屏幕上看不到任何内容 一切都是黑色的 我得到以下事件日志 模拟器 glTexImage2D 出错了 0x506 内部 0x1908 格式 0x1908 类型 0x1401 我已经
  • HERE 地图:更改路线已行驶部分的颜色

    导航时可以改变路线的颜色吗 具体来说 我希望路线中已行驶的部分的颜色与即将行驶的部分的颜色不同 现在都是同一个颜色 将 MapRoute 对象的 TravelColor 变量设置为透明对我来说很有效 mapRoute color Resou
  • 如何修改 Skobbler 注释而不重新添加它

    我必须修改 SKAnnotation 的图像 注释生成器代码 private SKAnnotation getAnnotationFromView int id int minZoomLvl View view SKAnnotation a
  • Android:监听状态栏通知

    有没有办法在状态栏被下拉时监听通知 1 用于检测状态栏变化 您可以注册一个监听器来获取系统UI可见性变化的通知 因此 要在您的活动中注册侦听器 Detecting if the user swipe from the top down to
  • 模块中的类无法加载

    我正在开发一个 2D Unity android 游戏 其中我最近添加了 Firebase Beta SDK 但添加后FirebaseAnalytics unitypackage我面临的错误是 无法加载模块中的类 当我删除文件夹时Fireb
  • 在 KitKat 4.4.2 中获取 SDard 路径和大小

    我在 Google Play 上有一个设备信息应用程序 在该应用程序中我有存储信息 我知道 Android 4 4 在访问外部 SD 卡方面发生了一些变化 内部似乎没有给我带来问题 我的问题是 如何可靠地获取 KitKat 上 SD 卡的大
  • Android studio - 如何查找哪个库正在使用危险权限?

    我正在尝试将 apk 上传到 google play 商店 但令我惊讶的是 我正在使用以下权限 Your APK is using permissions that require a privacy policy android perm
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 使用单选按钮更改背景颜色 Android

    我试图通过从单选组中选择单选按钮来更改应用程序选项卡的背景 但是我不确定如何执行此操作 到目前为止我已经 收藏夹 java import android app Activity import android os Bundle publi
  • Android应用程序可以像旧的普通java小程序一样嵌入到网页中吗?

    我对 android 平台一无所知 也无法在互联网上找到这个基本问题的答案 更新 好的 我本身无法嵌入 Android 应用程序 但是我可以在 Android Webbrowser 中嵌入 Java 的东西吗 不可以 您无法将 Androi

随机推荐