Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 完成froim线程时活动未停止_Android_Multithreading_Android Intent_Splash Screen - Fatal编程技术网

Android 完成froim线程时活动未停止

Android 完成froim线程时活动未停止,android,multithreading,android-intent,splash-screen,Android,Multithreading,Android Intent,Splash Screen,我有一个Splashscreen,我正在运行动画。以下是我关于从启动屏幕移动到main活动的逻辑 启动屏幕的最短可见时间=minTime 启动屏幕的最大可见时间=maxTime 调用API,该API在某个时间内得到响应—apiTime 1.显示启动屏幕至少minTime 2.调用API。如果在小于maxtime的时间内收到API的响应, 立即移动到下一屏幕,否则,请在中移动到下一屏幕 maxtime 以下是我的代码: public class SplashActivity extends App

我有一个Splashscreen,我正在运行动画。以下是我关于从启动屏幕移动到
main活动
的逻辑

启动屏幕的最短可见时间=
minTime

启动屏幕的最大可见时间=
maxTime

调用API,该API在某个时间内得到响应—apiTime

1.显示启动屏幕至少
minTime

2.调用
API
。如果在小于
maxtime
的时间内收到API的响应, 立即移动到下一屏幕,否则,请在中移动到下一屏幕
maxtime

以下是我的代码:

public class SplashActivity extends AppCompatActivity {

private ImageView container;
private AnimationDrawable animationDrawable;
int apiTime = 2000, minTime = 1000, maxTime = 5000;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    container = findViewById(R.id.iv_icons);
    container.setBackgroundResource(R.drawable.splash_animation);

    animationDrawable = (AnimationDrawable) container.getBackground();
}

@Override
protected void onResume() {
    super.onResume();
    animationDrawable.start();
    final long start = System.currentTimeMillis();

    //calling api in thread simultaneously. As soon as response is received, move to next screen.
    //Thread.sleep is just dummy for api response time
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(apiTime);
                //if apiTime is less than minTime, then we wait till minTime
                long time = minTime - (System.currentTimeMillis() - start);
                if (time > 0) {
                    Thread.sleep(time);
                }
                moveToNextScreen();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
    t1.start();

    hardMoveToNextScreen();
}

private void moveToNextScreen() {
    Intent i = new Intent(SplashActivity.this, MainActivity.class);
    startActivity(i);
    finish();
}

private void hardMoveToNextScreen () {
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            moveToNextScreen();
        }
    }, maxTime);
}

}
现在,根据我使用的时间值,线程
t1
调用方法
moveToNextScreen()。因此,一旦活动完成,我应该转到
MainActivity

我面临的问题是,
MainActivity
正在打开两次。一次从线程,然后从
hardMoveToNextScreen()
方法。但是,这不应该发生,因为我已经在调用
finish()
,这意味着一旦我移动到
MainActivity
,就不应该再调用
SplashActivity
中的任何方法


我做错了什么?

您两次调用moveToNextScreen()。第一次在线程中,第二次在hardMoveToNextScreen()中

如果删除hardMoveToNextScreen();在t1.start()之后;对你来说应该很好

或者更好的选择是删除线程,并使用hardMoveToNextScreen()方法和处理程序

最新答复:

如果要保留双逻辑声明全局变量:

private boolean activityFinished = false;
然后将moveToNextScreen()方法更改为:

private void moveToNextScreen() {
    if( !activityFinished ) {
        Intent i = new Intent( SplashActivity.this, MainActivity.class );
        startActivity( i );
        finish();
        activityFinished = true;
    }
}

您正在调用moveToNextScreen()两次。第一次在线程中,第二次在hardMoveToNextScreen()中

如果删除hardMoveToNextScreen();在t1.start()之后;对你来说应该很好

或者更好的选择是删除线程,并使用hardMoveToNextScreen()方法和处理程序

最新答复:

如果要保留双逻辑声明全局变量:

private boolean activityFinished = false;
然后将moveToNextScreen()方法更改为:

private void moveToNextScreen() {
    if( !activityFinished ) {
        Intent i = new Intent( SplashActivity.this, MainActivity.class );
        startActivity( i );
        finish();
        activityFinished = true;
    }
}

首先,我将告诉你们为什么会发生这种情况,然后,我将着手解决这个问题

原因:

即使在调用onDestroy()方法之后,活动实例仍保留在内存中。这并不意味着活动实例将永远留在那里。基于系统的内存需求,它被Android操作系统销毁。 这一点在这个答案中得到了很好的描述- 这一个也是- (此外,关于StackOverflow,有许多答案描述了完全相同的事情。只需搜索一下即可)

解决方案:

使用isDestroyed()方法,该方法返回一个布尔值,以检查是否调用了活动的onDestroy()方法。您可以在此处找到其文档-

所以moveToNextScreen()方法现在应该是这样的-

private void moveToNextScreen() {
    if (!isDestroyed()) {
        Intent i = new Intent(SplashActivity.this, MainActivity.class);
        startActivity(i);
        finish();
    }
}

首先,我将告诉你们为什么会发生这种情况,然后,我将着手解决这个问题

原因:

即使在调用onDestroy()方法之后,活动实例仍保留在内存中。这并不意味着活动实例将永远留在那里。基于系统的内存需求,它被Android操作系统销毁。 这一点在这个答案中得到了很好的描述- 这一个也是- (此外,关于StackOverflow,有许多答案描述了完全相同的事情。只需搜索一下即可)

解决方案:

使用isDestroyed()方法,该方法返回一个布尔值,以检查是否调用了活动的onDestroy()方法。您可以在此处找到其文档-

所以moveToNextScreen()方法现在应该是这样的-

private void moveToNextScreen() {
    if (!isDestroyed()) {
        Intent i = new Intent(SplashActivity.this, MainActivity.class);
        startActivity(i);
        finish();
    }
}

你能用:if(!isFinishing)来调节你的方法吗。这可能会确保其中任何一个方法都不会执行。是否可以使用:if(!isFinishing)来调整方法。这可能会确保其中任何一个方法都不会执行。是的,我知道我调用了moveToNextScreen()两次。这正是我需要做的。我只希望调用其中一个方法,即来自Thread或hardMoveToNextScreen()的方法。这应该是这样的,因为我最终从两个地方调用finish,所以无论首先执行什么,都应该完成splash活动。我已经在我的项目中复制了您的代码,并进行了一些双重检查。在线程和处理程序中的moveToNextScreen()上放置断点,并在startActivity(i)方法上放置另一个断点。运行debug,您将看到startActivity被调用了两次。我知道它被调用了两次。这就是问题所在!嗯,好吧,我不清楚你想保持这两种逻辑。请检查更新的答案。这应该对你有用。是的,我知道我调用moveToNextScreen()两次。这正是我需要做的。我只希望调用其中一个方法,即来自Thread或hardMoveToNextScreen()的方法。这应该是这样的,因为我最终从两个地方调用finish,所以无论首先执行什么,都应该完成splash活动。我已经在我的项目中复制了您的代码,并进行了一些双重检查。在线程和处理程序中的moveToNextScreen()上放置断点,并在startActivity(i)方法上放置另一个断点。运行debug,您将看到startActivity被调用了两次。我知道它被调用了两次。这就是问题所在!嗯,好吧,我不清楚你想保持这两种逻辑。请检查更新的答案。这应该适用于您。我已在我的计算机上亲自执行此代码,它工作正常,并且仅创建了一个您要求的MainActivity实例。我已在我的计算机上亲自执行此代码,它工作正常,并且仅创建了一个MainActivity实例