

Androidアプリ開発初心者です。  
Android Studio 2.0で作成をしていて、今まで、実機テストを、android.4.1.2(API 16)で行ってきました。  
特に問題もなく、スムーズに動いてくれていました。

ある程度できた後、 android.6.0.1(API 23) で実機テストをしてみました。  
すると、動作はカクカクしてしまい、まともに動きません。  
キー入力も反応が悪く、入力もできません。

API16では、HTCと、xperiaタブレットで試して、どちらも問題なし。  
API23では、xperia xと、DIGNOで試して、どちらもNGでした。

どういった理由で上記状況になってしまうのか、全く分からず困っています。  
どんな可能性があるのか、ご教授頂けると助かります。  
よろしくお願いいたします。

不具合の出ている具体的な個所としては、Animationをしようした、動きで、特に他の動作・効果音等が重なった際NGとなる。  
また、timer.scheduleを使用した画像に入れ替えも飛び飛びでコマ落ち状態です。  
効果音は、SoundPoolを使用しています。

何かしらのヒントでもあれば助かります。よろしくお願いいたします。

メインの文面抜粋

* * *
[code]

     //音楽の読み込み・設定
    p = MediaPlayer.create(getApplicationContext(), R.raw.s_m_map01);
    p.setLooping(true);//連続再生ON
    p.setVolume(0.4f, 0.4f);
    
    //効果音設定
    sp = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
    sound_id[0] = sp.load(this, R.raw.s_s_map00, 1);
    sound_id[1] = sp.load(this, R.raw.s_s_map01, 1);
    sound_id[2] = sp.load(this, R.raw.s_s_map02, 1);
    
    //定期実行スタート(基本　0.175秒毎)
    timer.schedule(anim, 0L, 175L);
    
    
    
    // 0.175秒ごとに実行**********************************************************************
    TimerTask anim = new TimerTask() {
        public void run() {
            if (App.power == 0 && power_0 == true){
                power_0 = false;
             }else{
                power_0 = true;//パワーがなくなると、２回に１回の処理へ
    
                if (kyara_i_t != 0) {
                    //移動アニメーション実行へor実行中--------------------
                    hdl.post(new kyara_i_jikkou());//移動実行
                    } else if (((ImageView) findViewById(R.id.map_b1)).isPressed() || ((ImageView) findViewById(R.id.map_b2)).isPressed() || ((ImageView) findViewById(R.id.map_b3)).isPressed() || ((ImageView) findViewById(R.id.map_b4)).isPressed()) {
                    //移動無実行で、キーが長押しされた場合---------------------
                    if (input == 1) {
                        kyara_i_t = 1;
                        if (((ImageView) findViewById(R.id.map_b1)).isPressed()) kyara_i = 1;
                        if (((ImageView) findViewById(R.id.map_b2)).isPressed()) kyara_i = 2;
                        if (((ImageView) findViewById(R.id.map_b3)).isPressed()) kyara_i = 3;
                        if (((ImageView) findViewById(R.id.map_b4)).isPressed()) kyara_i = 4;
                        hdl.post(new kyara_i_jikkou());//移動実行
                    }
                } else {
                    //何もなされてなければ、足踏み実行----------------------
                    hdl.post(new kyara_anim());//足踏み実行
                    }
                }
            }
        };
    
    // キャラクターのアニメーション実行（足踏み）**************************
        class kyara_anim implements Runnable {
            public void run() {
                //キャラクター足踏み画像へ変更
                int i;
                kyara_anim++;
                if (kyara_anim == 5) kyara_anim = 1;
                if (kyara_anim == 4) i = 2;
                else i = kyara_anim;
    
                img_id = "kyara";
                img_file = "kyara_" + kyara_no + "_" + kyara_m + "_" + i;
                img_img(img_file, img_id);
            }
        }
    
[/code]

以上、一部抜粋してみました。該当箇所になるかわかりませんが、  
よろしくお願いします。  
（初めて作ったandroidプログラムで汚いですが、よろしくお願いします。）

* * *

ご回答、大変ありがとうございます。参考になります。  
早速頂いたプログラムに変更してみましたが、状況は改善できませんでした。

その他、ご教授頂いた件について、ご回答いたします。

img_imgについて

[code]

    private void img_img(String img_file2, String img_id2) {
            //画像の変更　img(画像データ,どの名前？)*******************************************************************************************************
            String[] stArrayData = img_file2.split("\\.");
            int mon_id = getResources().getIdentifier(stArrayData[0], "drawable", getPackageName());//リソースの取得
    
            String[] stArrayData2 = img_id2.split("\\.");
            int mon_id2 = getResources().getIdentifier(stArrayData2[0], "id", getPackageName());//リソースの取得
    
            ((ImageView) findViewById(mon_id2)).setImageResource(mon_id);
        }
    
[/code]

画像を切り替えるプログラムとなっています。

CPUモニターについて  
Android6.0 = CPUは30％位です。  
Android4.1 = CPUは1％位です。  
大きな差があります。

GPUモニターについて  
Android6.0 =  
Swap Buffers が100～200msとふり切れています。  
たまにMisc Time も10msを超えています。  
画像を前もって読み込んでいないのが原因でしょうか？  
Android4.1 =  
表示してくれませんでした？？

その他メモリーについて  
Android6.0 = CPUは250MB位です。  
Android4.1 = CPUは120MB位です。  
解像度の違いからでしょうか？  
元々、数字が大きいのが気になります。  
インストール時のファイルサイズは、30MB位です。

以上、お手数をおかけいたしますが、よろしくお願いいたします。

追記**************************************************************************  
Android4.1で通常通り動くことから初期設定に何か問題あるのかなとも  
考えたんですが、下記の「build.gradle」は関係ないでしょうか？

①クラス

[code]

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.0.0'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    allprojects {
        repositories {
            jcenter()
        }
    }
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
[/code]

②app

[code]

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            applicationId "**********************************"
            minSdkVersion 15
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        // 追加
        applicationVariants.all { variant ->
            if (variant.buildType.name.equals("release")) {
                variant.outputs.each { output ->
                    if (output.outputFile != null
                            && output.outputFile.name.endsWith('.apk')) {
                        // .apk名の付け替え newNameを必要に応じて変更すること
                        def versionName  =defaultConfig.versionName
                        def newName      ="vs_v${versionName}.apk"
                        output.outputFile=new File(output.outputFile.parent,newName)
                    }
                }
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.3.0'
        compile 'com.google.android.gms:play-services-ads:7.5.0'
        compile 'com.google.code.gson:gson:2.4'
    }
    
[/code]

よろしくお願いいたします。


CC BY-SA 3.0
2016-08-14T06:32:18.563
28255
2016-09-27T10:44:02.447
2016-08-15T03:51:17.387
18468
18468
question
android
APIが古いと軽快なのはなぜですか？


はっきりした原因は分からないですが、いくつか改善できそうです。  
問題が解決できなかもしれませんがご参考までに。

**1.**  
0.175秒毎に実行される処理の中で重たい処理をされているようです。`findViewById`
の呼び出しと、kyara_animクラスとkyara_i_jikkouクラスのインスタンス生成は避けたほうが良いです。

次のプログラムはイメージですが、先に
`findViewById`で見つけた`ImageView`と、kyara_animとkyara_i_jikkouをインスタンス変数に入れておき、animの中ではそちらを参照するのはどうでしょうか？

[code]

    private Runnable kyara_i_jikkou_runnable;
    private Runnable kyara_anim_runnable;
    
    private ImageView map_b1;
    private ImageView map_b2;
    private ImageView map_b3;
    private ImageView map_b4;
    
    // 0.175秒ごとに実行**********************************************************************
    TimerTask anim = new TimerTask() {
        public void run() {
            if (App.power == 0 && power_0 == true) {
                power_0 = false;
    
            } else {
                power_0 = true;//パワーがなくなると、２回に１回の処理へ
    
                if (kyara_i_t != 0) {
                    //移動アニメーション実行へor実行中--------------------
                    hdl.post(kyara_i_jikkou_runnable);//移動実行
                } else if (map_b1.isPressed() || map_b2.isPressed() || map_b3.isPressed() || map_b4.isPressed()) {
                    //移動無実行で、キーが長押しされた場合---------------------
                    if (input == 1) {
                        kyara_i_t = 1;
                        if (map_b1.isPressed()) kyara_i = 1;
                        if (map_b2.isPressed()) kyara_i = 2;
                        if (map_b3.isPressed()) kyara_i = 3;
                        if (map_b4.isPressed()) kyara_i = 4;
                        hdl.post(kyara_i_jikkou);//移動実行
                    }
                } else {
                    //何もなされてなければ、足踏み実行----------------------
                    hdl.post(kyara_anim_runnable);//足踏み実行
                }
            }
        }
    };
    
    //メソッド名は適当ですが、初期化処理としてみてください。
    void init() {
        ...
    
        map_b1 = (ImageView) findViewById(R.id.map_b1);
        map_b2 = (ImageView) findViewById(R.id.map_b2);
        map_b3 = (ImageView) findViewById(R.id.map_b3);
        map_b4 = (ImageView) findViewById(R.id.map_b4);
    
        kyara_i_jikkou_runnable = new kyara_i_jikkou();
        kyara_anim_runnable = new kyara_anim();
    
        ...
    }
    
[/code]

**2.**  
`img_img`メソッドの中で頻繁に画像切り替えているので、次のように改善できそうです。

  * もし画像のバイト数が大きければ小さくしてみる。
  * 事前に画像のBitmapを読み込んでおいてそれで差し替える or LevelListDrawable を使うともしかするとキャッシュが効いて負荷がさがるかもしれません。

LevelListDrawable  
<https://developer.android.com/reference/android/graphics/drawable/LevelListDrawable.html>  
<http://y-anz-m.blogspot.jp/2010/11/androidlevellistdrawable.html>

**3.**  
AndroidStudioでしたら、CPUモニターとGPUモニターが付いていますので、  
そちらをみるとアニメーションが遅くなっている原因の手がかりになると思います。  
<https://developer.android.com/studio/profile/am-gpu.html>  
<https://developer.android.com/studio/profile/am-cpu.html>


CC BY-SA 3.0
2016-08-15T01:22:58.730
28266
2016-08-15T02:51:42.363
2016-08-15T02:51:42.363
15228
15228
28255
answer