从服务开始活动需要太长时间

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 内部的接口事件方法上启动了意图 是的,你需要什么? 您的示例项目以重现问题。

以上是关于从服务开始活动需要太长时间的主要内容,如果未能解决你的问题,请参考以下文章

第一次从推力执行排序需要太长时间

SQL Server:清理旧数据需要太长时间

Hive:修改外部表的位置需要太长时间

在 GPS 芯片长时间处于活动状态后,Android 设备需要重启/重启才能获取 GPS 位置

为啥 azure 需要这么长时间才能创建 Windows 核心服务器容器实例?

mysql左连接需要太长时间