Deprecated Thread methods are not supported without stop() method - java

I programmed game, which is supposed to use .startActivity on activity which should display score, the problem is, that instead of properly displaying the activity, i'm getting "Deprecated Thread methods are not supported". I googled this error and i removed all Thread.stop() in my application, but it did not helped. Could there be any other reason why i'm getting this type of error?
public class GameFrame extends Activity implements OnTouchListener, OnLossListener {
Panel game;
#Override
public void onCreate(Bundle savedInstanceState) {
Display d=getWindowManager().getDefaultDisplay();
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Point p=new Point(d.getWidth(),d.getHeight());
game=new Panel(this,p);
setContentView(game);
game.setOnTouchListener(this);
game.setOnLossListener(this);
}
public boolean onKeyDown (int kc,KeyEvent ke){
if (kc==23){
game.shoot();
}
return true;
}
public void onPause(){
super.onPause();
game.thread.setState(false);
game.mech.setState(false);
this.finish();
}
#Override
public boolean onTouch(View v, MotionEvent me) {
if (v.equals(game)){
game.setPosOfPlane((int)me.getX());
}
return true;
}
#Override
public void lost(int score) {
Intent i=new Intent (this,EndGame.class);
i.putExtra("score",score+"");
startActivity (i);
}
}

Use Thread.currentThread().interrupt(); instead stop();
Hope it helps cya!

I can't tell you what exactly is the problem, but I can give you some hints.
First of all you usually create a thread when starting your application and let it run until you want to exit your game (user pressed BACK). Other than that you only pause your game thread, e.g. when you're displaying another activity or your app is temporarily suspended (user pressed HOME).
If you want to end your game thread, just let it die naturally. Usually such thread runs in some sort of a loop, so you just exit this loop and the thread will terminate on its own. You usually call join() on the game thread from the main thread to block it until the game thread dies.
You should never manipulate thread's state directly.

Related

Android - pause and continue thread

In my Activity I create a Thread for multiply objects and "save" them to a hashmap. Is it possible to pause just a single thread of the hasmap and continue it?
public void onCreate(Bundle savedInstanceState) {
Thread oThread = new Thread(new Runnable() {
public void run() {
while (true) {
// doing some work
}
}
}
oThread.start();
aThreads.put(name, oThread);
}
public void anyMethod(){
// here I want to start and continue a thread
aThreads.get(name).stop();
aThreads.get(name).resume();
}
But .stop() and .resume() aren't working :/ any suggestions?
Use a boolean variable to control the thread exection.
ie.
while(!isThreadRunning){
...your statements
}
Once you are moving out of the screen in OnPause method make the variable false/true based on your usage to stop the thread execution.And you have to take care of the persisting hashmap.

Where to put AsyncTask so that it's only started once

Right now I have a Timer starting an AsyncTask in a Fragments onCreate method (with a timer interval of 1 minute). So that is not a good idea I believe because if there is a configuration change the fragment will call the onCreate method again and I will have 2 running Timer AsyncTasks right?
So I need some way to put the AsyncTask where it's only started once during the whole lifecycle of the app.
no need of Asynctask for simple timer, try this -
class MyFragment extends Fragment{
private int currentTime;
private void startTimer(){
new Handler().
postDelayed(new Runnable(){
#Override
public void run()
{
onTick();
startTimer();
}
},1000*60);
}
private void onTick()
{
currentTime++;
}
#Override
public void onSaveInstanceState(Bundle outState)
{
outState.putInt("currentTime", currentTime);
super.onSaveInstanceState(outState);
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
{
currentTime=savedInstanceState.getInt("currentTime",0);
startTimer();
}
}
You could use a Countdown Timer and cancel it in onDestroy(). That would guarantee that you only have a single one running at any time.
As for starting it exactly only once you will have to persist that knowledge somewhere depending on your needs. Maybe storing a boolean in onSaveInstanceState and reading it in onCreate() would do the trick?
And, as #marcin_j has pointed out, AsyncTasks are executed in sequence (unless specifically started differently), so using one will block every other Async task in your app (like downloading stuff etc).
if there is a configuration change the activity gets destroyed and re-created so no you will not have 2 timers running

How to Control Multiple threads of Same Object?

following is inside my button click in android
protected onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState)
public void onClick(View arg0)
{
if(connectThread!=null)
{
connectThread.kill();
}
connectThread=new ConnectThread(device);
connectThread.start();
}
}
I have made a boolean volatile variable running in ConnectThread class which is true by default and kill method will set it value to false.
Problem is that still it is not working the reason may be that in my ConnectThread run method im creating another thread but that should not be the problem since that gets called from the run method and since that will be child thread of ConnectThread; on killing connectThread that will automatically get cancelled?
kill method of ConnectThread
public void kill()
{
running=false;
}
run method of ConnectThread
public void run()
{
while(running)
{
}
}
If the app was still active on your device, and you started a second connection thread, the bluetooth device might not be available.
I recommend you read up on the Android Activity Lifecycle.

Null pointer error due to thread not stopping before orientation change

I have a fragment that displays weather data that runs a background thread that essentially just calls a function in my main UI to check whether my forecast is still valid. This function updates the UI so I am using a Handler and posting a Runnable to the main thread, like so:
public class WaveFxListFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener {
// .....
// handler for dealing with synchronising update thread with UI
private Handler mHandler;
private UpdateThread mUpdateThread;
private class UpdateThread extends Thread {
volatile boolean running = false;
#Override
public void run() {
running = true;
while (running) {
// get main UI thread to perform update check:
Log.d(TAG, "Handler is " + mHandler);
mHandler.post(new Runnable() { // getting null pointer error here!
#Override
public void run() {
checkValidTime();
}
});
try {
Thread.sleep(1000); // sleep 1 second
} catch (InterruptedException e) {
Log.d(TAG, "Thread was interrupted!");
e.printStackTrace();
}
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Reuse existing handler:
mHandler = getActivity().getWindow().getDecorView().getHandler();
}
#Override
public void onResume() {
super.onResume();
// start update checker:
mUpdateThread = new UpdateThread();
mUpdateThread.start();
}
#Override
public void onPause() {
// stop update thread
Log.d(TAG, "Asking thread to stop");
mUpdateThread.running = false;
super.onPause();
}
}
This works fine; the problem is when I change my screen orientation. The current activity gets destroyed and if the thread is running, it tries to post a Runnable to a UI thread that no longer exists. So, I put a running member variable in the UpdateThread class and set if to false when my activity goes calls onPause. However, even though I have set the UpdateThread.running variable to false, my thread still tries to post a Runnable, but the Handler is now null! It shouldn't get that far, but it is!
Am I doing this wrong? My log message "Asking thread to stop" gets printed out, so I know it is getting as far as setting running to false.
Can anyone offer an insight?
Thanks
A few things that you can do to resolve this.
Interrupt the thread after you set running to false. This should cause the thread to exit earlier, or at the very least for your error to appear earlier.
Check that your handler is not null in your update thread, and set it to null in onPause.
Move the assignment of mHandler to onResume to make sure that mHandler is valid when the update thread is called.

Taking heavy computation off the Android UI Thread

My Android app employs a particularly big computation which keeps crashing the system because it is on the UI thread in the Activity.
I have little confidence in multithreading and so I want to get some tips on how to do it correctly.
This is what I have
class ActivtyName extends Activity{
boolean threadcomplete = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//stuff
Runnable newthread = new Runnable(){
#Override
public void run() {
doBigComputation();
threadcomplete=true;
}
};
newthread.run();
boolean b = true;
while(b){
if(threadcomplete){
b=false;
startTheApp();
}
}
}
}
Now, I am pretty sure what I have done is not "correct". (It seems to work though. The sistem doesn't crash). Basically, I'm not sure how the UI thread can be told that newthread has finished the computation without this boolean, threadcomplete. Is there a "correct" way to do this?
Just to expand a bit on Marek Sebera's comment, here's the framework on how you would accomplish that in an AsyncTask.
private class BigComputationTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Runs on UI thread
Log.d(TAG, "About to start...");
}
#Override
protected Void doInBackground(Void... params) {
// Runs on the background thread
doBigComputation();
}
#Override
protected void onPostExecute(Void res) {
// Runs on the UI thread
Log.d(TAG, "Big computation finished");
startTheApp();
}
}
And to call it:
BigComputationTask t = new BigComputationTask();
t.execute();
In addition to Marvin's answer, there's a good article on the Android developer site about precisely this.
That's not the correct way to start a thread. You need to do:
Runnable newthread = new Runnable(){
#Override
public void run() {
doBigComputation();
threadcomplete=true;
}
};
Thread t = new Thread(newthread);
newthread.start();
boolean b = true;
while(b){
if(threadcomplete){
b=false;
startTheApp();
}
}
When i want to use threads, I've almost a big while loop. I put a boolean condition who's always true, except when I want to stop it.
I use Thread (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html) and I reimplement the stop method because it's deprecated. So in my stop method I can put a false value to the loop variable.
To terminate the thread, I use t.stop(). So you can di that in your activity.
If you want to know when a Thead stops, you can use t.isAlive(). If the thread t is started, isAlive will return true.

Categories

Resources