2017-01-09 22 views
0

私はこのアンドロイドプロジェクトを持っている、それはRAMを食べている理由を識別することはできません?私はちょうどRAMが記入されている処理がないことに注意してください。私はAndroid RAM issueshow to solveを読みましたが、何をすべきかを知ることはできません。私はアンドロイドとjavaの両方に新しいです。おそらくアンドロイドのメモリリーク

私のアプリはわずか4MBのメモリしか使用していません(Android Monitor - RAM)。 誰でも実行しようとすると(MainActivityはランチャーであり、MyCanvasはViewとして使用されるクラスに過ぎません)、これは100倍のスピード変数を使用できます。さらに10ms以内にスレッドコールを戻すことができます。それは何の問題も生じません。しかし、私がタッチして移動するとすぐにガベージコレクタはすべてを一時停止します。 (ビューとして使用)

MyCanvas.java

package com.abc.mygraphics; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.view.View; 

import java.util.Random; 
import android.os.Handler; 

public class MyCanvas extends View { 

public static Paint paint; 
//public static int n = 5000; 
public static int N = 100, particleSize = 3; 
public static int height, width; 
public static float[][] pos = new float[N][2]; 
public static float[][] pos0 = new float[N][2]; 
//public static float distX, distY, dist; 
Handler handler = new Handler(); 
public static int speed = 1; 
public static int gravityX, gravityY; 
public static Random random = new Random(); 
public static int[] colorList = new int[10]; 
public static int sphereSize = 100, M = 10; 
public static float[] distance = new float[N]; 
public static int[][] gravity = new int[N][2]; 
public static boolean[] direction = new boolean[N]; 
public static int[] moved = new int[N]; 

public MyCanvas(Context context) { 
    super(context); 

    width = MainActivity.sharedPreferences.getInt("screenX", 200); 
    height = MainActivity.sharedPreferences.getInt("screenY", 200); 
    colorList = new int[]{Color.RED, 0xffff4000, 0xffffff00, 0xff40ff00, 0xff00ff00, 0xff00ff80, 0xff0080ff, 0xff0000ff, 0xffbf00ff, 0xffff0040}; 

    paint = new Paint(); 
    paint.setColor(Color.GRAY); 
    int i; 
    for (i = 0; i < N; i++) { 
     pos[i][0] = random.nextInt(width); 
     pos[i][1] = random.nextInt(height); 
     pos0[i][0] = pos[i][0]; 
     pos0[i][1] = pos[i][1]; 
     moved[i] = 0; 
     direction[i] = true; 
    } 

    final Runnable r = new Runnable() { 
     public void run() { 
      invalidate(); 
      handler.postDelayed(this, 100); 
     } 
    }; 
    handler.postDelayed(r, 100); 
} 

public static void changeGravity(){ 
    gravityX = MainActivity.sharedPreferences.getInt("x",200); 
    gravityY = MainActivity.sharedPreferences.getInt("y",200); 
    // gravityY -= 68; 
    for(int i=0;i<N;i++){ 
     calcDist(i); 
    } 
} 

@Override 
public void onDraw(Canvas canvas){ 
    int i; 
    int x; //remove at some poitnt 
    canvas.drawColor(Color.BLACK); 
    //canvas.drawCircle(gravityX,gravityY, 50, paint); 

    for(i=0;i<N;i++) { 
     setPosition(i); 
     x = random.nextInt(10); 
     paint.setColor(colorList[x]); 
     canvas.drawCircle(pos[i][0], pos[i][1], particleSize, paint); 
    } 
} 

public static void setPosition(int i){ 
    // this is wrong 
    if(moved[i] >= (int)distance[i]/speed){ 
     direction[i] = !direction[i]; 
     setGravity(i); 
    } 
    else{ 
     pos[i][0] = pos0[i][0] + speed*moved[i]*(gravity[i][0]- pos0[i][0])/distance[i]; 
     pos[i][1] = pos0[i][1] + speed*moved[i]*(gravity[i][1]- pos0[i][1])/distance[i]; 
     moved[i]++; 
    } 
} 

public static void calcDist(int i){ 
    setGravity(i); 
    distance[i] = (float) Math.sqrt(Math.pow((gravity[i][0]-pos[i][0]),2) + Math.pow((gravity[i][1]-pos[i][1]),2)); 
} 

public static void setGravity(int i){ 

    // do not forget to set pos0 in both cases 
    if(direction[i]){ 
     gravity[i][0] = gravityX; 
     gravity[i][1] = gravityY; 
    } 

    else{ 
     // make this biased on radius of sphere 
     gravity[i][0] = random.nextInt(width); 
     gravity[i][1] = random.nextInt(height); 
    } 
    pos0[i][0] = pos[i][0]; 
    pos0[i][1] = pos[i][1]; 
    moved[i]=0; 
} 



} 

メインActivity.java

package com.abc.mygraphics; 

import android.content.SharedPreferences; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.view.MotionEvent; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.EditText; 
import android.widget.TextView; 

import com.abc.mygraphics.MyCanvas; 

import org.w3c.dom.Text; 

public class MainActivity extends AppCompatActivity { 

//DrawingView dr = new DrawingView(this); 

public static SharedPreferences sharedPreferences; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 


    DisplayMetrics displaymetrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
    int height = displaymetrics.heightPixels; 
    int width = displaymetrics.widthPixels; 


    sharedPreferences = getSharedPreferences(getPackageName() + "_preferences", MODE_PRIVATE); 

    SharedPreferences.Editor editor = sharedPreferences.edit(); 
    editor.putInt("screenX",width); 
    editor.putInt("screenY", height); 
    editor.putInt("x", 200); 
    editor.putInt("y", 200); 
    editor.commit(); 
    setContentView(new MyCanvas(this)); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    // int x = (int)event.getX(); 
    //int y = (int)event.getY(); 
    int x = (int) event.getRawX(); 
    int y = (int) event.getRawY(); 
    //sharedPreferences = getSharedPreferences("CheckSharing",Context.MODE_PRIVATE); 
    SharedPreferences.Editor editor = sharedPreferences.edit(); 
    editor.putInt("x", x); 
    editor.putInt("y", y); 
    editor.apply(); 
    MyCanvas.changeGravity(); 

    return false; 
} 

} 
+0

'MyView'の' Handler'のように、 'MyView'クラスが漏れている可能性があり、' Handler.postDelayed'を使用しているために関連付けられている 'Activity'もリークします。一時的に 'Handler'の使用をコメントアウトし、メモリの問題がまだ存在するかどうかを確認してください(これがコード内の唯一のリークであると仮定してください)。そうでなければ、いくつかの可能な修正について議論することができます。 –

+0

また、私の推測が正しければあなたの編集に基づいて、カスタムビューをホストするアクティビティの新しいインスタンスが毎回作成されるように、ポートレートモードとランドスケープモードの間でデバイスを前後に回転させるにつれてメモリ使用量が増加し続けるはずです。 –

+0

ハンドラーの代わりに何を使うのですか??率直に言って私はスレッドの作業のアイデアを持っていない私はそれが私が欲しいものを行うbeacauseを使用した。なぜなら私はViewの継続的なリフレッシュが必要なので。私が望むのは、Particle Flow(Playストアで検索)のようなアプリです。 –

答えて

0

は私の問題を得ました。 タッチイベントが発生するたびに私のメソッドを呼び出そうとしていましたが、マウスをドラッグすると文字通り何千ものタッチイベントが発生するので、これはできません。

コードから理解してください。主なアクティビティでは、changeGravity()メソッドを呼び出すonTouchイベントリスナーがあり、これはcalcDist()およびsetGravity()(calcDist()から)を呼び出します。だから、たくさんのガベージが生成されてGCが再生され、アプリケーションが一時停止し、すべてがハングアップしているように見えます。

解決策 - calcDist()呼び出しをスレッド内に置くだけで、重力の大きさは10msで有効になります。これは、私たちがchangeGravity()メソッドから呼び出すとどうなるかと比べて、私たちのエミュレータと携帯電話が可能なものです。

関連する問題