Home » Android » android – Start activity from service takes too long

android – Start activity from service takes too long

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a Service that when one function gives to me true it will start a new Activity but it takes like 5 seconds…

I’ve read about this issue, and I’ve found on StackOverflow this example to “avoid” this bug..

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
try {
   pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
   e.printStackTrace();
}

but sadly it doesn’t start the Activity faster, I don’t need to be inmmediate (better if it’s possible), but I don’t want to wait +5 seconds to launch the new Activity, do you knwo any trick to avoid this?

I’m using PendingIntent because I’ve found that guy that said that it should solve this issue :
Starting an activity from a service after HOME button pressed without the 5 seconds delay

Note

If I press back button it launch it autommatically, 0 delay, but I’m looking pressing the home button.

How to&Answers:

I cannot comment everywhere yet, so I’m putting this solution of a similar problem as an answer

After much digging, found out the cause of the problem. Apparently
it’s not a bug, it is a feature which does not allow Services or
BroadcastReceivers to launch activities for up to 5 seconds after home
button is pressed. No easy way to overcome this.

More info here:
https://code.google.com/p/android/issues/detail?id=4536

I replaced the activity with a Window added to the window manager of
the running service. This does not cause any delay.

Source link Stackoverflow

Answer:

First thing we cannot update any UI related stuff in service, neither calling activity nor updating any UI elements, 
Same problem i too have faced.

Then i have used EventBus library to communicate UI elements from service 
Below is the sample example

public class SendSPLocationService extends Service {
Handler mHandler = new Handler();
Thread downloadThread;
boolean isRunning = true;
private VolleyHelper volleyHelper;

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    //  Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
    volleyHelper = new VolleyHelper(this);

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    final Timer t = new Timer();
    t.schedule(new TimerTask() {
        @Override
        public void run() {
            Log.d("run: ", "service is running!");

            try {
                                        EventBus.getDefault().post(new FutureJobEvent(false, error.networkResponse.statusCode, errorJson.getString("message")));

            } catch (JSONException e) {
                e.printStackTrace();
            }
            // t.cancel();
            Log.d("run: ", "service is stopped!");

        }
    }, 0, 5000);
    return START_STICKY;
}
}

Use below code for triggered event to observe..either in activity/fragment

@Override
public void onStart() {
    super.onStart();
    if (!EventBus.getDefault().isRegistered(this))
        EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    super.onStop();
    if (EventBus.getDefault().isRegistered(this))
        EventBus.getDefault().unregister(this);
}
 @Subscribe(threadMode = ThreadMode.MAIN)
 public void onMessageEvent(TrackSPEvent event) {
    if (event.success) {
         startActivity(new Intent(this,MainActivity.class));
 }
 }

Answer:

I tested with the PendingIntent approach and couldn’t find anything wrong. That seems to be working fine. However, for reference, here is what I tried at my end:

public class MyService extends Service {
    public static final String SERVICE_COMMAND = "COMMAND";
    public static final String TAG = "MyService";
    public static final int SERVICE_START = 0x01;
    public static final int START_ACTIVITY = 0x02;

    private class ServiceHandler extends Handler {
        public ServiceHandler(HandlerThread thread) {
            super(thread.getLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case START_ACTIVITY:
                    Intent ActivityIntent = new Intent(getApplicationContext(), TestActivity.class);
                    ActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
                            0, ActivityIntent, 0);
                    try {
                        pendingIntent.send();
                    } catch (PendingIntent.CanceledException e) {
                        e.printStackTrace();
                    }
                    Log.e(TAG, "Service started activity -> " + System.currentTimeMillis());
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    }

    private HandlerThread mThread;
    private ServiceHandler mHandler;

    public MyService() {
        mThread = new HandlerThread("ServiceThread");
        mThread.start();
        mHandler = new ServiceHandler(mThread);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int id = intent.getIntExtra(SERVICE_COMMAND, SERVICE_START);
        switch (id) {
            case START_ACTIVITY:
                Log.e(TAG, "onStartCommand Service -> " + System.currentTimeMillis());
                mHandler.sendEmptyMessage(START_ACTIVITY);
                break;
            default:
                break;
        }
        return START_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

Activity Code:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "Main";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "onCreate main activity -> " + System.currentTimeMillis());
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        Intent intent = new Intent(this, MyService.class);
        startService(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG, "onPause main activity -> " + System.currentTimeMillis());
        Intent intent = new Intent(this, MyService.class);
        intent.putExtra(MyService.SERVICE_COMMAND, MyService.START_ACTIVITY);
        startService(intent);
    }
}

You can try the same code at your end. May be it can help.