2016-05-04 1 views
2

私は意図的にnullポインタ例外を導入するアプリを持っています。コード例を次のように私はこれを説明します:プロセスの状態が終了したかどうかを確認する方法、あるいはこれが可能なのか?

// access modifiers omitted for brevity 
class MyApplication extends Application { 

    String name; 

    String getName() { 
     return name; 
    } 

    void setName(String name) { 
     this.name = name; 
    } 
} 

// ============================== ======

// access modifiers omitted for brevity 
class WhatIsYourNameActivity extends Activity { 

    void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.writing); 

     // Just assume that in the real app we would really ask it! 
     MyApplication app = (MyApplication) getApplication(); 
     app.setName("Developer Phil"); 
     startActivity(new Intent(this, GreetLoudlyActivity.class)); 

    } 

} 

// =================================== ===================

// access modifiers omitted for brevity 
class GreetLoudlyActivity extends Activity { 

    TextView textview; 

    void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.reading); 
     textview = (TextView) findViewById(R.id.message); 
    } 

    void onResume() { 
     super.onResume(); 

     MyApplication app = (MyApplication) getApplication(); 
     textview.setText("HELLO " + app.getName().toUpperCase()); 
    } 
} 

ユーザーがアプリを起動します。 WhatIsYourNameActivityでは、ユーザーの名前を尋ねて、それをMyApplicationに格納します。 GreetLoudlyActivityでは、MyApplicationオブジェクトからユーザーの名前を取得して表示します。 ユーザーはホームボタンを使用してアプリを離れる。 数時間後、Androidは暗黙的にアプリを殺してメモリを再利用します。

これまでのところ、とても良いです!

しかし、ここでcrashy一部を付属しています...

ユーザーはアプリを再オープンします。 Androidは新しいMyApplicationインスタンスを作成し、GreetLoudlyActivityを復元します。 GreetLoudlyActivityはユーザー名を取得します。ユーザー名はnullになり、NullPointerExceptionでクラッシュします。

Applicationオブジェクトが新品なのでクラッシュします。そのため、name変数はnullで、String#toUpperCase()を呼び出すとNullPointerExceptionが発生します。あなたがエミュレータや根ざし電話上でこれを実行する

コマンドライン、:、アプリを起動し、その後 :デバイス上で、コマンドライン上のホーム

adb shell ps 

プレス:

adb shell ps | grep com.crashy.package 

と:

adb shell kill <PID from above step> 

ここで、私たちはrecents apps tを使用してバックグラウンドからアプリを戻そうとしますabsとそれは意図したようにクラッシュします。問題は、プロセスと一緒に殺されたすべてのオブジェクトの状態を一覧表示する方法、またはプロセスを強制終了して関連するすべてのオブジェクトを終了させる方法です。このプロセスをフォークする方法はありますか?

+0

「WhatIsYourNameActivity」にユーザの名前を格納し、それを 'GreetLoudlyActivity'に' Intent Bundle'として渡してそこに格納することができます。 – Grender

+0

それは私の質問ではありません。私は意図的にこの問題を紹介しています。プロセスが強制終了されたときに何が起こるのかを分析したいと思います。強く参照されているオブジェクトはどうなりますか? – Skynet

+0

これは答えではありませんが、なぜアプリケーションクラスに名前を格納するのですか?なぜ共有プレフィックスにはありませんか? – varunkr

答えて

2

"...プロセスを強制終了すると、関連するすべてのオブジェクトが強制終了されますか?"

これはまさに何が起こるかです。プロセスが終了すると、所有されているすべてのメモリがOSによって再利用されます。そうしなければ、プロセスが終了してOSが最終的にメモリ不足になるたびにメモリリークが発生します。

プロセス/アプリケーションが終了すると、永久保存に保存されなかったものはすべて失われます。

-1

問題は、単純変数を使用して永続ストレージをシミュレートしようとしていることです。より理解を深めるために、Androidのアクティビティのライフサイクルを見て、いつ、どのようにアプリが「殺されたか」を確認します。http://developer.android.com/training/basics/activity-lifecycle/index.html

解決策として、共有設定マネージャを使用することをお勧めします。この

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this) 
Preferences.Editor edit = preferences.edit(); 
edit.putString('name', 'someName'); 
edit.commit(); 

と名前を保存して、あなたの他の活動にそれを取得し、ストレージの活動では

(あなたのデータはsqlLite DBを正当化するのに十分な大きさを見ていない)

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this) 
preferences.getString('name'); 
+0

それは私の質問ではありません。プロセスが強制終了されるとどうなりますか?プロセスはフォークされていますか?プロセスがフォークされるとどうなりますか?フォークプロセスの後、子プロセスのアドレス空間は新しいプロセスデータで上書きされます。これは、システムへのexec呼び出しによって行われます。 – Skynet

+0

フォーク・アンド・エグゼクティブ・メカニズムは、古いプログラムを新しいものに切り替えるのに対し、新しいプログラムが実行される環境は入力デバイスと出力デバイスの環境変数、環境変数、優先順位など、同じままです。このメカニズムは、すべてのUNIXプロセスを作成するために使用されるため、Linuxオペレーティングシステムにも適用されます。プロセスID 1の最初のプロセスinitも、いわゆるブートストラップ手順でブート手順中にフォークされます。 – Skynet

+0

オブジェクトはどこにありますか? – Skynet

関連する問題