これに似た質問をオンラインで見つけることができなかったので、質問を送信しようと思いました。ほとんどの場合、タッチ イベント中に遅延が発生する可能性があるという逆の問題を抱えているようですが、私は正反対のことを確認しています。私はエアホッケーゲームを作成しており、各フレームは現在のパラメーターに基づいてピースが移動し、バックグラウンドでオーバーライド ontouch リスナーがモーションイベントを探している間にゲームが再描画されます。問題は、指が画面に触れておらず、アニメーションの部分を見ているだけの場合に顕著な遅延があることですが、何らかの形のモーション イベントが発生している限り、ontouch が呼び出されている場合、アニメーションはスムーズです。これがなぜなのか、まったく理解できませんが、
すべてがどのように構成されているかについて、もう少し背景を説明します。クラス全体は Main.java にあり、ここで作成され、Context ビューを要求します。ゲーム クラスは ImageView の拡張です。ゲーム クラスには @override OnTouchEvent があり、これには、どの状態とどのモーション イベントに応じて何を行うかについてのすべての定義があります。このクラスには draw メソッドもあり、メソッドの最後で h.postDelayed(r, FRAME_RATE); を呼び出します。ここで、r は、invalidate(); を呼び出すだけの @Override public void run() を持つ Runnable です。h は、クラスで初期化される単なるハンドラーです。そのため、ゲームが描画されるたびに、10ms の FRAME_RATE 経過時間後に無効化が呼び出され、ゲームに再描画を指示します。ゲームのすべての移動関数も draw メソッドから呼び出されます。OnTouch はこのプロセスと並行して行われているため、OnTouch が呼び出されている場合、真かどうかを確認するよりもスムーズになるのはなぜですか。すべて直感に反しているように見えますが、論理的な理由があると確信しています。最後に、ラグ タイムはシステム クロックを使用して測定可能であり、正確に呼び出された場所に基づいて時間に依存していました。タッチ イベントが発生していないときに、ゲーム移動機能間の通過時間が増加したことを示しています。
実際のコード コンテキストがあまりない長い応答で申し訳ありませんが、十分に説明できることを願っています。コード自体はかなり長いので、それを投稿するのに役立つとは思いませんでしたが、必要に応じて、視覚化された階層を使用して疑似コードを再投稿することでよりうまくいくことができます. この問題に関するご助言とご提案をありがとうございます。なぜそれが起こっているのかを理解できることは素晴らしいことです。
これがコードです。元の投稿を編集して投稿する必要があることに気づきませんでした。
public class Main extends Activity {
Game game;
private Menus menus; // contains menu info
int menu; //keep track of what menu you are at
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
game = new Game(this);
setContentView(game);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
..some code here to process photo files
}
//get the orientation of loaded pictures
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if (cursor.getCount() != 1) {
return -1;
}
cursor.moveToFirst();
return cursor.getInt(0);
}
public void Keyboard()
{
use keyboard listener and perform some actions if...
}
public class Game extends ImageView{
private Game game;
//Touch Events
boolean pressed;
private Context mContext;
private Handler h;
private final int FRAME_RATE = 10;
boolean initDimension = false;
//constant for defining the time duration between the click that can be considered as double-tap
static final int MAX_DURATION = 500;
Bitmap background;
int HEIGHT;
int WIDTH;
public Game(Context context) {
super(context);
mContext = context;
h = new Handler();
//ModeInit(); // load up puck game mode
menu = 0; //after tap from ontouch changes to menu = 1 for game
}
private Runnable r = new Runnable() {
@Override
public void run() {
invalidate();
}
};
@Override
public boolean onTouchEvent(MotionEvent e)
{
Switch Statement...
CHECK MOTION EVENT TYPE
CHECK menu state.. perform action
}
public void ModeInit()
{
game = new Game( mContext, WIDTH, HEIGHT );
}
protected void onDraw(Canvas c)
{
if(!initDimension)
{
WIDTH = this.getWidth();
HEIGHT = this.getHeight();
initDimension = true;
}
else
{
//logo screen
if(menu == 0)
{
menu = menus.DisplayIntro(c);
}
//game mode
else if(menu == 1)
{
game.paint_game(c);
long run_test = System.nanoTime()/1000;
game.Move();
Log.d("run time: ",": "+(System.nanoTime()/1000-run_test)); //Ontouch LAG TEST
}
... other menu items here
}
h.postDelayed(r, FRAME_RATE);
}
}
}