从服务开始活动需要太长时间
Posted
技术标签:
【中文标题】从服务开始活动需要太长时间【英文标题】:Start activity from service takes too long 【发布时间】:2018-04-17 20:42:47 【问题描述】:我有一个Service
,当一个函数给我true
时,它将启动一个新的Activity
,但它需要大约5秒...
我已经阅读了这个issue
,并且我在***
上找到了这个示例来“避免”这个错误..
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();
但遗憾的是它不会更快地启动Activity
,我不需要立即(如果可能的话更好),但我不想等待 +5 秒来启动新的Activity
,你知道有什么技巧可以避免这种情况吗?
我正在使用PendingIntent
,因为我发现那个人说它应该解决这个问题:
Starting an activity from a service after HOME button pressed without the 5 seconds delay
注意
如果我按下back button
,它会自动启动它,0 延迟,但我正在寻找按下home button
。
【问题讨论】:
你为什么首先从服务开始活动? 为什么你使用挂起的意图,而不是直接启动活动 因为我想检测用户何时执行某些操作,并且我从我的服务中计算它,所以当用户执行该操作时它会启动 Activity。 @Rahul 编辑了我的问题 从其他活动开始活动时是否会出现相同的延迟? 【参考方案1】:我还不能到处评论,所以我把这个类似问题的解决方案作为答案
经过大量挖掘,找到了问题的原因。显然 这不是一个错误,它是一个不允许服务或 BroadcastReceivers 启动活动后最长可达 5 秒 按钮被按下。解决这个问题没有简单的方法。
更多信息在这里: https://code.google.com/p/android/issues/detail?id=4536
我用添加到窗口管理器的窗口替换了活动 正在运行的服务。这不会造成任何延迟。
来源链接***
【讨论】:
希望对您有所帮助! 但它的功能和activity不一样吧?我的 Activity 上有东西....如何将 Activity 更改为 Window?检查它是否对我有价值。【参考方案2】:首先,我们无法更新服务中的任何 UI 相关内容,既不能调用 Activity,也不能更新任何 UI 元素,我也遇到过同样的问题。
然后我使用 EventBus 库与服务中的 UI 元素进行通信下面是示例示例
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;
使用下面的代码来观察触发事件..在活动/片段中
@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));
【讨论】:
但是有了那个库,你可以在那个延迟的情况下启动一个 Activity 吗? 但是您的事件总线将不再被注册,因此永远不会调用 onMessageEvent。我认为 OP 想要的是 ...Intent dialogIntent = new Intent(this, MyActivity.class); dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(dialogIntent);
... 对我来说,当我将它放入服务中并且它需要不到 5 秒的时间时,它就可以工作,但我认为这取决于手机,也许还取决于 API 级别。我猜 OP 已经尝试过了,因为它是你在 searching 时找到的第一个。【参考方案3】:
我使用 PendingIntent 方法进行了测试,没有发现任何问题。这似乎工作正常。但是,作为参考,这是我最后尝试的:
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;
活动代码:
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);
您可以在最后尝试相同的代码。可能会有帮助。
【讨论】:
我在 Serivce 内部的接口事件方法上启动了意图 是的,你需要什么? 您的示例项目以重现问题。以上是关于从服务开始活动需要太长时间的主要内容,如果未能解决你的问题,请参考以下文章
在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置