@VidarWahlberg您的答案很好,但是假设您FragmentActivity
在运行任务的地方打开了新FragmentActivity
的,在异步结束或您的应用程序在后台运行之前打开(例如:您单击了主页)。我建议你创建BaseActivity
你扩展的地方,你FragmentActivity
的所有活动都应该扩展它。
什么是重要的?
正如@VidarWahlberg 在他的回答中提到的那样,您需要拥有 ,并在子活动中使用它来BaseActivity
显示.static FragmentManager fm;
DialogFragment
有什么区别?
fm = getSupportFragmentManager();
而不是在方法中初始化,onStart()
您需要在onResume()
. 这是必需的,因为当您启动线程运行活动时,它正在创建它的新实例,并且在启动下一个活动时,它会创建将被初始化的新实例,BaseActivity
并且FragmenManager
当您回到线程启动活动fm
对象时,将使用第二个活动(暂停)实例。应用程序将崩溃,因为您将尝试在已暂停的活动视图中显示对话框。您无法更改暂停活动的视图,因此您需要在onResume()
调用时进行初始化。onResume()
在活动开始时也会调用,因此在FragmentManager
那里初始化是安全的!
我们还需要担心什么?
你可能认为一切都很好,但事实并非如此。您可能第一次没有意识到,但是如果您的应用程序不在前台(而是在后台),您的所有活动都将暂停,但线程已经启动并且正在运行。这是一个问题,因为线程将继续并尝试显示DialogFragmernt
(或者假设更改未聚焦的活动视图)。所以解决方案是跟踪应用程序是否在前台。这可以完成,PackageManager
但它需要清单文件中的新权限(用户不喜欢,他们可能不想安装您的应用程序)。解决方案是static boolean isOnBackground = false;
在每个活动中onResume()
使用isOnBackground = false;
和 in更改字段。这不是很大的变化,因为onPause()
isOnBackground = true;
BaseActivity
是我们可以做到的地方。这是安全的,因为每次新活动的开始都会创建BaseActivity
类的新实例,但由于该字段static
只创建一次并且对于所有实例都是相同的。我们需要isOnBackground
在启动线程 post 方法的主体代码之前检查状态。
您可能会说由于 和 之间的延迟可能会出现问题onPause()
,onResume()
但是您的应用程序需要以快速启动活动的方式进行设计,而不是在 ui 线程上做长时间的工作(需要在后台线程上完成)。因此,如果您的应用程序设计良好,您将不会遇到问题 :)
只要应用程序不在前台,您就可以使用线程运行方法的递归调用。这是安全的,不会导致循环,因为当应用程序的状态被重置(需要内存)或应用程序被用户停止或 android 本身循环将停止,因为所有应用程序的实例都将从内存中释放!
注意:使用 android 支持库!
代码如下:
BaseActivity.java
.......................
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
.......................
public class BaseActivity extends FragmentActivity {
public static FragmentManager fm;
public static boolean isOnBackground;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
BaseActivity.isOnBackground = false;
BaseActivity.fm = getSupportFragmentManager();
}
@Override
protected void onPause() {
super.onPause();
BaseActivity.isOnBackground = true;
}
}
MainActivity.java
.....................
import android.support.v4.app.DialogFragment;
.....................
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//This is just to call some second activity
Button startNewActivity = (Button) findViewById(R.id.helloWorld);
startNewActivity.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
showEditDialog();
}
private void showEditDialog() {
(new Handler()).postDelayed(new Runnable() {
@Override
public void run() {
if(!BaseActivity.isOnBackground) {
DialogFragment myFragmentDialog = new DialogFragment();
myFragmentDialog.show(BaseActivity.fm,
"fragment_my_dialog");
} else {
//this is optional
showEditDialog();
}
}
}, 15000);
}
}