简体   繁体   中英

android activity create multiple instance of my thread

i need to check a variable for change, if the change happens i will update a textview.

so i created a new thread with a while loop for this purpose. i check the variable every 1 second, via Thread.sleep()

this thread created and started in onCreate(). so it's one time.

the problem is every time i flip my phone (from vertical to horizontal or ...) a new thread will be created.

here is my code:

public class HomeActivity extends Activity
{
private final static int LOAD_SUCCESSFULL = 1;
private final long LOCATION_THREAD_SLEEP = 1000;    
private boolean flag = false;   
static TextView lat;
static TextView lon;    
static Location currentLocation = null; 
Thread locationThread;

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);        
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.new_home2);
    this.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.new_home_titlebar);

    lat = (TextView)findViewById(R.id.t2rt3);
    lon = (TextView)findViewById(R.id.t2rt4);

    /* FindLocation class is a helper class that find location via simcard or gps in separate thread,
        same problem happen with this thread also, it create multiple thread, for ease of work i 
        commented this part.
    */      
    //FindLocation fn = new FindLocation(this);

    locationThread = new Thread(null, loadLocation, "loadLocationHomePage");

    locationUpdater();
}

private static Handler locationUpdateHandler = new Handler()
{
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
        case LOAD_SUCCESSFULL:
            lat.setText(Double.toString(currentLocation.getLatitude()));
            lon.setText(Double.toString(currentLocation.getLongitude()));
            //stopThread();
            break;              
        }
    }
};

private Runnable loadLocation = new Runnable()
{
    public void run()
    {
        //boolean flag = false;
        while(!flag)
        {
            if(Data.currLocation != null)
            {                   
                currentLocation = new Location(Data.currLocation);                  
                Message msg = locationUpdateHandler.obtainMessage(LOAD_SUCCESSFULL);                    
                locationUpdateHandler.sendMessage(msg); 
                //return;
                flag = true;
                //return;
            }               
            else
            {
                try 
                {
                    Thread.sleep(LOCATION_THREAD_SLEEP);
                } 
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }               
        }
    }
};

public void locationUpdater()
{
    //Thread locationThread = new Thread(null, loadLocation, "loadLocationHomePage");
    locationThread.start();
}

so how i can solve this?

在此处输入图片说明

Actually the problem is that EveryTime you flip the phone a new instance of Activity is created and because of this you on every rotation you get a call on onCreate() where you are blindly creating a new Thread and Starting the new Thread .

This is the default behavior of every Activity but we can change this re-creation of Activity by stating an attribute in AndroidManifest file for the Activity

<activity
    android:name="yourPackage.ActivityName"
    android:configChanges="keyboardHidden|orientation|screenSize"
</activity>

This will prevent from creation of Activity on orientation change.

You will also get these orientation event if you override

@Override
        public void onConfigurationChanged(Configuration newConfig) {}

Hope this will solve this problem without implementing such a complex logic which may broke in some other uses case.

I think you aren't perhaps going about this in the most efficient way possible.

But if your question is simply, how do i prevent multiple worker threads from being spawned, you should look into a UIless fragment.

http://www.vogella.com/articles/AndroidFragments/article.html#headlessfragments1

i don't know why android doing this. if i putted my code in onResume(), then this behavior make sence but in my case, i don't know.

anyway i found a dirty solution. the idea is finding list of all thread and search them for mine, if it existed prevent to create another.

public boolean checkThreadExist()
{
    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]);
    for(int i = 0; i < threadArray.length ; i++)
    {
        if(threadArray[i].getName().equalsIgnoreCase("loadLocationHomePage"))
            return true;
    }

    return false;
}

updated onCreate() :

if(checkThreadExist())
    {

    }
    else
    {
        locationThread = new Thread(null, loadLocation, "loadLocationHomePage");            
        locationUpdater();            
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM