Android 完成froim线程时活动未停止
我有一个Splashscreen,我正在运行动画。以下是我关于从启动屏幕移动到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
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实例