my thread in java is showing errors [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am a beginner to android development. I have been trying to work this splashscreen with a audio file that kills itself after 3 secs. Then my Mainactivity is supposed to start. But my code is showing some error which i cannot figure out.the code n the java class is as follows:`
public class splash extends Activity {
MediaPlayer mySound;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
mySound=MediaPlayer.create(splash.this, R.raw.crowd_sound);
mySound.start();
}
Thread kill_Thread= new Thread(){
public void run(){
try {
sleep(3000);
Intent splash_intent=new Intent(splash.this,MainLFC.class);
startActivity(splash_intent);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
finish();
}
}
};
kill_Thread.start();
#Override
protected void onPause() {
super.onPause();
mySound.release();
}
}
the manifest file is as follows:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainLFC"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.inten**strong text**t.action.MAINLFC" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>

To get the behavior you pretend you must call your thread from within the onCreate method. For this you have two options, either keep using your thread and define it inside onCreate before calling it's start, or just use a Handler. Bellow theres your onCreate method for both options.
Using Thread.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
mySound=MediaPlayer.create(splash.this, R.raw.crowd_sound);
mySound.start();
Thread kill_Thread= new Thread(){
public void run(){
try {
sleep(3000);
Intent splash_intent=new Intent(splash.this,MainLFC.class);
startActivity(splash_intent);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
finish();
}
}
};
kill_Thread.start();
}
#Override
protected void onPause() {
super.onPause();
mySound.release();
}
Using Handler
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
mySound=MediaPlayer.create(splash.this, R.raw.crowd_sound);
mySound.start();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Intent splash_intent=new Intent(splash.this,MainLFC.class);
startActivity(splash_intent);
finish()
}
}, 3000);
}
#Override
protected void onPause() {
super.onPause();
mySound.release();
}

Starting a new activity should be done in the main (UI) thread.
If you want to communicate your thread with the main thread you can use a Handler and there start a new activity.
Example Handler:
Handler hander = new Handler(){
public void handleMessage(Message m){
Intent splash_intent=new Intent(splash.this,MainLFC.class);
startActivity(splash_intent);
}
};
Example sending a msg to the handler:
Thread kill_Thread= new Thread(){
public void run(){
try {
sleep(3000);
hander.sendMessage(Message.obtain());
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
finish();
}
}
};
kill_Thread.start();

try this outside your on create method:
public class kill_Thread extends Thread{
public void run(){
try {
sleep(3000);
runOnUiThread(new Runnable() {
#Override
public void run() {
Intent splash_intent=new Intent(splash.this,MainLFC.class);
startActivity(splash_intent);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
finish();
}
}
};
where you declare your public variables set:
public kill_Thread kt;
and in your OnCreate call:
kt.start();

Related

Android app opens after a few seconds after pressing home button during splash screen

I am having an issue I can't seem to figure out the reason for.
When you launch the app, a splash screen is first displayed for 2.5 seconds before finishing and starting a new activity. If you press the home or back button during this time the app will close as normal. However after a few seconds (longer than 2.5) the app will open and start from the activity that comes after the splash screen.
Any help on why this happens is appreciated!
Here is the implementation of the Splash screen (I do however not believe anything here causes this issue as I've tried different implementations)
`public class SplashScreenActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Thread myThread = new Thread(){
#Override
public void run() {
try {
sleep(2500);
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
myThread.start();`
Here's the manifest
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
android:launchMode = "singleInstance">
</activity>
<activity android:name=".activities.SplashScreenActivity"
android:theme="#style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".alert.BroadCaster" >
</receiver>
<service android:name=".timer.TimerService"
android:process=":timerservice" />
</application>
It happens because you are creating a new Thread and this thread will be still alive after you put your app in background. You can change your approach using an Handler. If you need that your next Activity won't start if the splash screen is in background, you have to store the current time before the delay starts.
private static final long SPLASH_SCREEN_MS = 2500;
private long mTimeBeforeDelay;
private Handler mSplashHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
// Create a new Handler.
mSplashHandler = new Handler();
}
#Override
protected void onResume() {
super.onResume();
// The first time mTimeBeforeDelay will be 0.
long gapTime = System.currentTimeMillis() - mTimeBeforeDelay;
if (gapTime > SPLASH_SCREEN_MS) {
gapTime = SPLASH_SCREEN_MS;
}
mSplashHandler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(intent);
SplashScreenActivity.this.finish();
}
}, gapTime);
// Save the time before the delay.
mTimeBeforeDelay = System.currentTimeMillis();
}
#Override
protected void onPause() {
super.onPause();
mSplashHandler.removeCallbacksAndMessages(null);
}
Just use handler instead of thread sleep like this
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(intent);
SplashScreenActivity.this.finish();
}
}, SPLASH_DURATION);
You need to implement the onStop() method, only if you want to save data and memory.

Why wont my splash screen work?

I'm pretty new to Java and xml i'm looking to have a splash screen run when i start up my app for about 5 seconds. I've taken code for the splash screen from stack overflow to set it up but i cant get it to run for some reason could anybody help me out!
Cheers
MY splash class
package com.darraghoflaherty.competer.game;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
public class Splash extends Activity {
/** Duration of wait **/
private final int SPLASH_DISPLAY_LENGTH = 5000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splashscreen);
/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,Menu.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
My xml code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099FF">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/ss1"
android:id="#+id/ss1"
android:textColor="#ffffff"
android:textSize="260sp"/>
</RelativeLayout>
first change this peace of code :
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,Menu.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
To
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(getApplicationContext(),Menu.class);
startActivity(mainIntent);
finish();
}
Now your code is clear, the error must come from the manifest file.
Go to the manifest file and change the position of the intent-filter from the Mainactivity to the slashscreen activity.
here the code :
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
My guess is that you have not changed the launcher activity in the manifest. Android looks in the AndroidManifest.xml to select the activity to start first. Your manifest probably contains these lines:
<activity android:name=".Menu" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This should be changed to:
<activity android:name=".Splash" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Menu"/>
It is also a good convention to name activities XyzActivity, so in your case MenuActivity and SplashActivity.
/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
Thread timer = new Thread(){
public void run(){
try{
Thread.sleep(2000);
}
catch(InterruptedException e){
e.printStackTrace();
}
finally{
Intent mainIntent = new Intent(Splash.this,Menu.class);
startActivity(mainIntent );
finish();
}
}
};// end thread
timer.start();
use this code for the splash screen ...
public class SPLASH extends Activity {
protected boolean _active = true;
protected int _splashTime = 3000; // time to display the splash screen in MICROSECONDS
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while (_active && (waited < _splashTime)) {
sleep(100);
if (_active) {
waited += 100;
}
}
} catch (Exception e) {
} finally {
startActivity(new Intent(Splash.this,Menu.class));
finish();
}
};
};
splashTread.start();
}
}
and make the Splash activity a launcher activity by using
<activity
android:name=".SPLASH"
android:label="#string/app_name"
android:theme="#style/NoActionBar"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Hope this will help u
Hey checkOut it i have improve little bit. thanks
public class Splash extends Activity {
private final int SPLASH_DISPLAY_LENGTH = 5000;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splashscreen);
nav();
}
public void nav() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent mainIntent = new Intent(Splash.this,Menu.class);
startActivity(mainIntent);
finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}

Hang up and decline incoming call by custom activity[buttons] Android

I am just in process by learning Android a bit, and i have stumbled on this problem.
I want to do a "custom incoming call screen". My current Solution is a class(IncomingCallInterceptor) that extends from BroadcastReceiver. In IncomingCallInterceptor class i override the onReceive and starting my activity(MainActivity) with layout when the phone is ringing.
In that activity(MainActivity) i have three buttons:
Accept Call, Hang Up, Decline Call
Those buttons should do what they say, Answer the phone, hang up the phone or decline the call.
I have in someway got the Accept Call to work, but not Hang Up and Decline.
Heres my code below:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.uppgift.six.one.incoming61.sixone" >
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="IncomingCallInterceptor">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
IncomingCallInterceptor that extends from BroadcastReceiver:
public class IncomingCallInterceptor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String msg = "Phone state changed to " + state;
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {
String incomingNumber = intent.getStringExtra
(TelephonyManager.EXTRA_INCOMING_NUMBER);
msg += ". Incoming number is this " + incomingNumber;
//START MY ACTIVITY!
Intent i = new Intent(appContext, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(i);
}
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
Here is my Activity(The Layout is nothing to post, just now is basically three buttons)
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnAnswer = (Button)findViewById(R.id.btnAnswer);
Button btnDecline= (Button)findViewById(R.id.btnDecline);
Button btnHangUp= (Button)findViewById(R.id.btnHangUp);
btnAnswer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(i, null);
}
});
btnDecline.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Decline Call (I need help here)
}
});
btnHangUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Hang Up Call (I need help here)
}
});
}
In the MainActivity class it is marked by comments where i need some help.
I have also seen something about a "Telephonyservice interface"(thingy) solution, but i don't understand how that worked when i was testing it.
Reject Call:
try {
TelephonyManager tm = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
}

Unable to redirect after Splash screen

I havesetup a splash screen from where I want it to redirect to my main activity after 5 sec but my application always stays on the splash screen and never redirects.
I have following code in my SplashActivity.Java
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.SplashActivity);
Thread timer = new Thread() {
public void run() {
try {
// sleep(R.integer.SplashActivityTime);
sleep(5000);
} catch (InterruptedException iEx) {
iEx.printStackTrace();
} finally {
Intent mainActivity = new Intent(
"com.myApp.myApp.MainActivity");
startActivity(mainActivity);
}
}
};
timer.start();
}
}
And in Manifest I Have:
<activity
android:name="com.myApp.myApp.SplashActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.myApp.myApp.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.myApp.myApp.MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Use this code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread timer = new Thread() {
public void run() {
try {
// sleep(R.integer.SplashActivityTime);
sleep(5000);
} catch (InterruptedException iEx) {
iEx.printStackTrace();
} finally {
Intent mainActivity = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(mainActivity);
finish();
}
}
};
timer.start();
}
And in manifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.sample.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.sample.SecondActivity"
android:label="#string/app_name" >
</activity>
</application>
Change your Intent:
Intent mainActivity = new Intent(this, MainActivity.class);
In addition, which class is the owner of that sleep method?
Remove intent-filter for main activity's activity in manifest file
And best way to implement splash screen click here
and starting intent line change to
Intent mainActivity = new Intent(SplashActivity .this, MainActivity.class);
use the following code
Thread logoTimer = new Thread()
{
#Override
public void run()
{
try
{
sleep(3000);
startActivity(new Intent(SplashActivity.this, MainActivity.class));
}//End of try block
catch (InterruptedException e)
{
e.printStackTrace();
}//End of catch block
finally
{
finish();
}//End of finally block
}//End of run method
};//End of anonymous thread inner class
logoTimer.start();
In Manifest
<activity
android:name="com.myApp.myApp.SplashActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.myApp.myApp.MainActivity"
android:label="#string/app_name" >
</activity>
Maybe Try this :
public class splashscreen extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash); // Your Splash Layout
Handler handler = new Handler();
// run a thread
handler.postDelayed(new Runnable() {
public void run() {
// make sure we close the splash screen so the user won't come back when it presses back key
finish();
// start the home screen
Intent intent = new Intent(splashscreen.this, TabDemo2Activity.class);
splashscreen.this.startActivity(intent);
}
}, 5000); // time in milliseconds (1 second = 1000 milliseconds) until the run() method will be called
}
}
use Handler as below it's work for me.
Handler handler = new Handler();
// run a thread after 2 seconds to start the home screen
handler.postDelayed(new Runnable() {
#Override
public void run() {
finish();
if (!mIsBackButtonPressed) {
// start next activity
Intent intent = new Intent(SplashScreen.this, SEOshopMainActivity.class);
startActivity(intent);
}
}
}, 2000); // time in milliseconds (1 second = 1000 milliseconds) until the run() method will be called

Switching between activities raises Thread error

I make an app with two windows, when I go from main window to the preferences one everything is fine, but when I try to return back to main activity app crashes with Thread already started error.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
startService(new Intent(this, MyService.class));
}
public void onResume(){
super.onResume();
}
// Initiating Menu XML file (menu.xml)
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.layout.menu, menu);
return true;
}
public void onBackPressed() {
super.onBackPressed();
stopService(new Intent(this, MyService.class));
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Update:
Here is the log from LogCat (I am using Eclipse):
09-30 11:59:17.348: D/AndroidRuntime(2917): Shutting down VM
09-30 11:59:17.348: W/dalvikvm(2917): threadid=1: thread exiting with uncaught exception (group=0x40aa7210)
09-30 11:59:17.368: E/AndroidRuntime(2917): FATAL EXCEPTION: main
09-30 11:59:17.368: E/AndroidRuntime(2917): java.lang.IllegalThreadStateException: Thread already started.
09-30 11:59:17.368: E/AndroidRuntime(2917): at java.lang.Thread.start(Thread.java:1045)
09-30 11:59:17.368: E/AndroidRuntime(2917): at com.examples.todolist.GameView$1.surfaceCreated(GameView.java:45)
The ManiFest file (activity from it):
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service
android:name="MusicService"
android:enabled="true">
</service>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="PreferencesActivity"></activity>
<service android:enabled="true" android:name=".MyService" />
</application>
In my project I have MainActivity.java - which is main window, PreferencesActivity.java - which is preferences window, GameView.java - which is responsible for drawing stuff and GameManager.java - which controls FPS. In game view I have main, onDraw and onTouch events.
Here is main from GameView:
public GameView(Context context) {
super(context);
gameLoopThread = new GameManager(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
bmp1 = BitmapFactory.decodeResource(getResources(),
R.drawable.wall_sprite);
}
Here is a gameManager.java, since I figured out that it is something to do with run. I still trying to figure out how to make thread (or screen?) destroyed and then make it again.
public class GameManager extends Thread {
static final long FPS = 30;
private GameView view;
private boolean running = false;
// class constructor
public GameManager(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {
}
}
}
}
Ok here is the deal, surfaceCreated() seems to hold a thread, and that thread can only be started once and only once. That is the immediate issue.
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
// This is unsafe
gameLoopThread.start();
}
Without knowing the entire design of your app there are a few ways this can be triggered multiple times.
A Surface can be created, destroyed and then a new surface can be created. In this case, the GameView would have the same thread reference and try to start it again. So you have Activity-A with SurfaceView. Creates Surface, then you start another activity, your surface view will probably be destroyed around the time of the onPause(). You finish your Preferences and come back to your activity, onResume() gets called and your surface will be recreated ... firing twice. This is all assuming that your app goes something like this:
Activity -> PreferencesActivity -> original Activity.
You seem to start another task so I am unsure why you do that, but the old activity is still on the backstack, so if it resumes, it will probably recreate the surface.
Not sure what GameManager is required for but it looks like a run loop of some sort. You can either make sure it isn't started if it already is. Or if there is a case where there may be desired separate GameManager instances, you could keep track of multiple instances and make sure not to start them again.

Categories