2017-06-08 9 views
0

これは私の最初のアプリで、基本的な質問です。私は、画面のロックやアプリの最小化などの中断に対処する方法を知りたいです。現在のところ、これらの両方でアプリが黒くなり、応答が停止します。Android、MainActivityはロック画面では生き残れません

アプリは1つのアクティビティ、つまり主なアクティビティで構成されています。ここでは、

GameSurface extends SurfaceView implements SurfaceHolder.Callback { ... } 

は、関連する「GameThread.java」スレッドを持つクラスである、と一緒に彼らは簡単なアプリを実行して、キャンバスに描きます。

がここにMainActivity.javaです:仕上げなし

public class MainActivity extends AppCompatActivity { 

final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
     | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
     | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
     | View.SYSTEM_UI_FLAG_FULLSCREEN 
     | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

    getWindow().getDecorView().setSystemUiVisibility(flags); 

    this.setContentView(new GameSurface(this)); 
} 


@Override 
protected void onPause() { 
    //finish(); 
    super.onPause(); 
} 

}

()onPauseで()、アプリはちょうど中断に対処することはできません。おそらくこれは、 "GameSurface"を保存していない、またはonResume()関数で回復できないsavedInstanceStateバンドルと関係がありますが、私はこの問題を理解していません。

はonPause()への仕上げを()追加すると、アプリが閉じるようになりますが、アプリの画像は、私のアプリのアイコンの後ろに、私のホーム画面の背景に背後に残ります。私はそれを中断するときにアプリを殺すことを望んでいないが、私はそれが簡単になるはずだと思ったので、私はアプリがきれいに閉じることができないのは興味がある。私は主な活動を終わらせるために別の方法を見つけることができないようです。アプリをきれいに終了させるための別の機能はありますか?

私の当面の目標は、画面がロックされた後、ロックが解除されたときにアプリの履歴書を持つことである、と私は、これは簡単な手順だろうと思ったが、私はそれを行う方法を見つけることができません。おそらく、私のアプリの構造が貧弱かもしれません。あなたは私がアプリを構造化できるより良い方法があれば、教えてください。全体のUIは、私が漫画の木などを描く単一のキャンバスです。

編集:私は主な活動における景観ように画面の向きを指定していることから、主な活動は、縦長のロック画面を表示するために破壊されなければならないことを Android Activity lifecycle and locking/unlocking device

:私は別の質問で読みました。それで、savedInstanceStateが悪いのでonCreate()は機能しませんが、なぜそれが悪いのか分かりません。また、画面の向きを変更することなく、アプリを最小限に抑えるだけで何が起こるかわからない。

編集:ここでは私のログが閉じて、その後、アプリを開くと、画面のロック、アンロックである:

(私は主な活動のいくつかのメソッドにログの命令を追加した)

[アプリケーションの開始、多くの通常のログ]

06-09 08:06:47.384 29697-29697/com.example.christian.androidgame2d W/System: ClassLoader referenced unknown path: /data/app/com.example.christian.androidgame2d-2/lib/arm 
06-09 08:06:47.388 29697-29697/com.example.christian.androidgame2d I/InstantRun: starting instant run server: is main process 
06-09 08:06:47.533 29697-29697/com.example.christian.androidgame2d D/log: onCreate 
06-09 08:06:47.587 29697-29697/com.example.christian.androidgame2d W/art: 
Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable 
06-09 08:06:47.837 29697-29697/com.example.christian.androidgame2d D/log: onstart 
06-09 08:06:47.837 29697-29697/com.example.christian.androidgame2d D/log: onresume 
06-09 08:06:47.859 29697-29735/com.example.christian.androidgame2d D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
06-09 08:06:47.957 29697-29735/com.example.christian.androidgame2d I/Adreno-EGL: <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 10/09/15, 6cbbf7d, I3193f6e94a 
06-09 08:06:47.968 29697-29735/com.example.christian.androidgame2d I/OpenGLRenderer: Initialized EGL, version 1.4 
06-09 08:06:48.206 29697-29697/com.example.christian.androidgame2d W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView 

アプリケーションは現在正常に実行されています。

06-09 08:07:22.852 29697-29697/com.example.christian.androidgame2d D/log: onPause 

                     [ 06-09 08:07:22.868 1735: 1835 D/   ] 
                     activate, handle: 1598182242, enabled: 0, index 2 

                     [ 06-09 08:07:22.868 1735: 1835 D/   ] 
                     BstSensorExt: id=1598182242, en=0 

                     [ 06-09 08:07:22.868 1735: 1835 D/   ] 
                     enable ID_SORI, path /sys/class/srot_sensor/g_sensor/en_disp_rotation, fd 248 
06-09 08:07:23.344 29697-29697/com.example.christian.androidgame2d D/log: ondestroy 

これ以上のロギング[Iは、画面のロックを解除] [Iは(電源ボタン)画面をロック]。しかし、アプリはフリーズした画像として表示されます。私はアプリを最小化し、次のようにそれはグリッチ:Buggy minimisation

ので)アプリが閉じられていないが、主な活動はonDestroy(と呼ばれています。私はアプリがどの段階にあるのかわかりません。

+0

はあなたをしていますアクティビティのライフサイクルに精通していますか?重要なアンドロイドのコンセプトhttps://developer.android.com/guide/components/activities/activity-lifecycle.html – nandsito

+0

はい、私はその記事を読んでいます。私は(私は質問にリンクします)私は部分的に私の質問に答えると思う別の質問が見つかりました。画面の向きは私のアクティビティによって設定されているので、ロック画面を表示するにはアクティビティが破壊されている必要があります。その後、ロック解除時にonCreate()が呼び出されます。すなわち、 MainActivityが再開します。しかし、なぜそれがきれいに再起動しないのかは明らかではありません。たぶん私は何が起こっているのかを見るためにいくつかのロギングを行うべきでしょう。 –

+0

電源ボタンが押されたとき、私はあなたの活動が破壊されていないと思っていますが、 'pause'dと' stop'pedだけです。次に、画面のロックが解除されると、 'start'と' resume'dが実行されます。はい、これらのコールバックにログインすると便利です – nandsito

答えて

0

一般的な概念の理解を向上させ、ログを記録した後、問題は実際には「GameSurface.java」にあることがわかりました。メソッドsurfaceDestroyed(SurfaceHolderホルダー)に、非終了whileループがありました。そう

風景は、私は画面をロックしたときにロック画面の向きが縦向きであるため、MainActivityは、onDestroy()を呼び出すようになりようの向きを設定し、:(重要ではない、単なるバグ)

私は逃した主なものそれは活動を破壊しなければならない。これは、私の活動がロックとアンロックの後にリセットされることを意味します。特に厄介なのは、そのメソッドがチュートリアルからコピーされたことです。

onPause()にfinish()を設定すると、画面をロックするとアプリケーションが終了しますが、最小化すると再オープンできなくなるため、これは悪い練習です/役に立たない。

アプリを中断することによって 'GameSurface'が破壊されているため、アプリを再開するために、GameSurfaceが行っていたことを保存するための方法が必要です(この場合はすべてのツリーのサイズと位置を保存します)。私の次の目標です。

私の修正は、 のgetWindow()。getDecorView()を使用することでした。setSystemUiVisibility(flags); onResume()の命令です。これまでのところ、ユーザーが戻ったときにアプリが再起動するようになっています。もはやそれはもはやクラッシュしない。

0

Android Activityライフサイクルへのアプリケーションのバインドを改善することをお勧めします。

初めてアプリを起動すると、Androidはアクティビティの方法としてonCreateonStart、およびonResumeのメソッドを呼び出します。 Androidでは、これらの方法でアプリを設定することが期待されています。私はあなたのアプリはこれらの罰金をやっていると信じて

ユーザーがあなたのアプリを離れて別のことをすると(電話に出かけたり、別のアプリに切り替えたり、電話をオフにするなど)、Androidはあなたのアプリがそれに応じて行動することを期待します。 Androidは、、onStop、およびonDestroyの方法を提供しています。 は、onResume,onStopからonStart、およびonCreateからonDestroyにミラーリングされています。

だから、あなたのアプリのために:

  • あなたがスレッドを開始言います。コールバックの1つでそれを停止する必要があります。
  • finishをに電話する必要はありません。 は、アプリの起動時などにオペレーティングシステムによって呼び出されます。フォーカスを失うが目に見える。アプリがいつでも完全に閉じる必要はありません。
  • アプリは、常に景観になりたい場合は、その後、作成、破棄、再度あなたの活動を作成する必要はありませんので、あなたは、あなたのマニフェストにこれを行うことができます:
<activity android:name="..." 
     android:screenOrientation="landscape"> 
関連する問題