アクティビティの破棄と再作成を行っても、私のアプリケーションに連続値を表示させようとしています。私はバックグラウンドスレッドを使ってFPSを維持しています。基本的にはメッセージをハンドラに送ります。アクティビティが破棄されて再作成されると、新しいハンドラが作成され、バックグラウンドスレッドの新しいインスタンスに送信されます。ただし、メッセージが受信されると、メッセージは「破棄された」アクティビティで実行されている元のハンドラによって受信されているように見えます。私よりも経験豊富な人がこれに重点を置くことができたら本当に感謝します!アクティビティを破棄して再作成するとき、ハンドラは古い破棄されたアクティビティインスタンスでまだ実行中です
マイコード(私はそれの少しより多くがあります知っているが、ほとんどすべての関連のonCreateで起こる):
public class MainActivity extends FragmentActivity {
final static int UPDATE_DISPLAY = 1;
//View Pager declarations
private static final int NUM_PAGES = 4; //Number of viewPager pages
private ViewPager mPager;
private ScreenSlidePagerAdapter mPagerAdapter;
private MainThread thread;
Fragment[] fragmentMap = new Fragment[NUM_PAGES];
//End view pager declarations
globalData gd;
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
//TESTING-------------
System.out.println("Received message from background thread.");
System.out.println("Handler receiving message is: "+this.toString());
System.out.println("Handler is running in activity: "+MainActivity.this.toString());
//---------------
if (msg.what == UPDATE_DISPLAY){
((TextView)findViewById(R.id.totalGas)).
setText("Gas: "+UnitValuePair.convertNumberToString(gd.getGasOwned()));
((TextView)findViewById(R.id.totalRock)).
setText("Rock: "+UnitValuePair.convertNumberToString(gd.getRockOwned()));
((TextView)findViewById(R.id.totalMetal)).
setText("Metal: "+UnitValuePair.convertNumberToString(gd.getMetalOwned()));
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("CREATING MainActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
Button resetButton = (Button)findViewById(R.id.resetButton);
resetButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resetData();
}
});
//Instantiate ViewPager and PagerAdapter
mPager = (ViewPager)findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setOffscreenPageLimit(5);
//Attach tablayout to view pager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(mPager);
//Init variable
gd = globalData.getInstance();
//Check if new game, and if so, init all base and actual values
Context context = getApplicationContext();
SharedPreferences sharedPref = context.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE);
//If first start, then init vals and mark that it has been started in shared preferences
boolean startedBefore = sharedPref.getBoolean("startedBefore", false);
Log.d("TEST", "Value of startedBefore boolean is:" + Boolean.toString(startedBefore));
if (!startedBefore)
{
gd.initVals();
gd.storeData();
gd.setNewGame(false);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("startedBefore", true);
editor.commit();
}
else
{
System.out.println("Restoring data");
gd.restoreData();
}
//TESTING---------
System.out.println("Handler seen by activity is: "+handler.toString());
System.out.println("New Activity is : "+this.toString());
//--------------------
//Start main update thread
thread = new MainThread((ViewGroup)findViewById(R.id.mainContainer), gd, handler, getApplicationContext());
thread.setRunning(true);
thread.start();
}
@Override
public void onPause()
{
System.out.println("PAUSING MainActivity");
super.onPause();
gd.storeData();
}
@Override
public void onResume()
{
super.onResume();
System.out.println("RESUMING MainActivity");
}
@Override
public void onBackPressed(){
if (mPager.getCurrentItem() == 0){
//If the user is currently looking at the first step, allow the system to handle
//back button. Calls finish() on activity and pops the back stack
super.onBackPressed();
} else {
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter
{
public ScreenSlidePagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem (int position)
{
switch (position) {
case 0:
CreationFragment newFragment0 = CreationFragment.newInstance(0);
fragmentMap[0] = newFragment0;
return newFragment0;
case 1:
UniverseFragment newFragment1 = UniverseFragment.newInstance(1);
fragmentMap[1] = newFragment1;
return newFragment1;
default:
return ScreenSlidePageFragment.create(position);
}
}
@Override
//Provides the titles of the fragments for use in tabLayout
public CharSequence getPageTitle(int position) {
String title=" ";
switch (position){
case 0:
title="Create";
break;
case 1:
title="Universe";
break;
case 2:
title="Upgrades";
break;
case 3:
title="Stats";
break;
}
return title;
}
@Override
public int getCount()
{
return NUM_PAGES;
}
}
@Override
protected void onDestroy(){
System.out.println("DESTROYING MainActivity");
//handler = null;
super.onDestroy();
}
public void resetData()
{
gd.initVals();
gd.setVisibilityChangedDisplay(true);
gd.setVisibilityChangedInv(true);
gd.setChangedDisplay(true);
gd.setChangedInv(true);
}
}
logcat:
は元のハンドラ、6402d8eは、で実行してアウトを開始活動108d9af。アクティビティーは、アクティビティー3112cf7として一時停止、破棄、再作成されます。新しいハンドラ、70420f6が作成され、新しいバックグラウンドスレッドに送信されます。バックグラウンドスレッドはメッセージの送信を開始し、受信しますが、受け取ったハンドラは元のスレッド6402d8eであり、アクティビティ108d9afで実行中であることを示します。
04-09 20:17:41.471 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Received message from background thread.
04-09 20:17:41.471 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Handler receiving message is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {6402d8e}
04-09 20:17:41.471 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Handler is running in activity: [email protected]
04-09 20:17:41.502 29339-29339/com.kessler.alexi.stellargrowth I/System.out: PAUSING MainActivity
04-09 20:17:41.502 29339-29339/com.kessler.alexi.stellargrowth D/TEST: Storing data
04-09 20:17:41.741 29339-29339/com.kessler.alexi.stellargrowth I/System.out: DESTROYING MainActivity
04-09 20:17:41.759 29339-29339/com.kessler.alexi.stellargrowth I/System.out: CREATING MainActivity
04-09 20:17:41.759 29339-29339/com.kessler.alexi.stellargrowth W/FragmentManager: moveToState: Fragment state for CreationFragment{a0042e2 #1 id=0x7f0d006d} not updated inline; expected state 1 found 0
04-09 20:17:41.759 29339-29339/com.kessler.alexi.stellargrowth W/FragmentManager: moveToState: Fragment state for UniverseFragment{66e2681 #2 id=0x7f0d006d} not updated inline; expected state 1 found 0
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth D/TEST: Value of startedBefore boolean is:true
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Restoring data
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth D/TEST: Retrieving data
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Handler seen by activity is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {70420f6}
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth I/System.out: New Activity is : [email protected]
04-09 20:17:41.775 29339-29339/com.kessler.alexi.stellargrowth I/System.out: New thread created. Handler seen by thread is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {70420f6}
04-09 20:17:41.805 29339-29339/com.kessler.alexi.stellargrowth I/System.out: RESUMING MainActivity
04-09 20:17:41.811 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Received message from background thread.
04-09 20:17:41.811 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Handler receiving message is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {6402d8e}
04-09 20:17:41.811 29339-29339/com.kessler.alexi.stellargrowth I/System.out: Handler is running in activity: [email protected]
---- UPDATE ------ 新しい活動は、新しいスレッドを開始しますが、メッセージを送信する1が破壊されている必要があります古いもののIDを持っている
04-10 10:43:41.149 19846-19846/com.kessler.alexi.stellargrowth I/System.out: New Activity is : [email protected]
04-10 10:43:41.149 19846-19846/com.kessler.alexi.stellargrowth I/System.out: New thread created with id: 23410
04-10 10:43:41.149 19846-19846/com.kessler.alexi.stellargrowth I/System.out: Handler seen by new thread is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {cf3308c}
04-10 10:43:41.149 19846-19846/com.kessler.alexi.stellargrowth I/System.out: Starting thread with id: 23410
04-10 10:43:41.180 19846-19878/com.kessler.alexi.stellargrowth I/System.out: Thread sending message is: 23405
04-10 10:43:41.188 19846-19846/com.kessler.alexi.stellargrowth I/System.out: RESUMING MainActivity
04-10 10:43:41.194 19846-19846/com.kessler.alexi.stellargrowth I/System.out: Received message from background thread.
04-10 10:43:41.194 19846-19846/com.kessler.alexi.stellargrowth I/System.out: Handler receiving message is: Handler (com.kessler.alexi.stellargrowth.MainActivity$1) {6402d8e}
04-10 10:43:41.194 19846-19846/com.kessler.alexi.stellargrowth I/System.out: Handler is running in activity: [email protected]
----- ANSWER ------ それがロックを取得し、基本的に、それは
@Override
protected void onDestroy(){
System.out.println("DESTROYING MainActivity");
thread.setRunning(false);
super.onDestroy();
}
に、以下に示すスレッドの実行コードを、onDestroy変更のちょうど問題だっ判明ブーリアンランニングが自動的に変更されないため、決してシャットダウンしません。新しいスレッドが開始されると、ロックを取得しようとしましたが失敗し、古いものが再び起動しました。
@Override
public void run() {
System.out.println("Thread "+this.getId()+" started.");
if (MainThread.lock.tryLock()) {
System.out.println("Thread "+this.getId()+" acquired lock");
try {
long tickCount = 0L;
while (running) {
tickCount++;
controlFPS(tickCount);
update();
}
} finally {
MainThread.lock.unlock();
}
}
}
なぜonPause()またはonDestroy()のハンドラ呼び出しを削除しないのですか? – rafsanahmad007
私はあなたが電話を外すことによって何を意味するか分かりません。私はnullにハンドラを設定しようとしましたが、それは何か違いがないようです。 –