这是我的情况:我正在构建一个Android游戏,我的游戏活动由一个自定义的SurfaceView组成,它有一个游戏逻辑和渲染的线程.该架构类似于Google网站上的LunarLander演示.
当活动开始时,它会创建surfaceView并调用此方法:
@Override
public void surfaceCreated(SurfaceHolder holder)
{
renderThread.start();
}
Run Code Online (Sandbox Code Playgroud)
当我按下主页按钮退出游戏时,会调用onPause()方法,该方法调用surfaceDestroyed().在surfaceDestroyed中,我通过调用来停止游戏Thread:
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
synchronized(holder)
{
renderThread.stop();
}
}
Run Code Online (Sandbox Code Playgroud)
该应用程序的背景很好.然后,当我通过按下图标重新启动应用程序时,我在日志中收到"Thread already started"消息以及屏幕上的"强制关闭"弹出窗口.当活动在渲染线程上调用start()时进入"surfaceCreated"方法时,会出现此消息.
现在我已经研究了几个小时,无法弄清楚为什么会这样.我相信当我关闭应用程序时我的线程已经停止,所以我不明白为什么它说它已经开始了.
我正在我的Android应用程序中实现Analytics,我想知道什么时候打电话 super.onPause()
if (mAnalyticsSession != null) {
mAnalyticsSession.close();
mAnalyticsSession.upload();
}
super.onPause();
Run Code Online (Sandbox Code Playgroud)
super.onPause()在执行上传操作之后调用会产生什么影响?
一般来说,何时应该打电话super.onPause()?
我希望我的Android应用程序的用户在按某个活动时退出我的应用程序.可以这样做吗?
我遇到了一些障碍.我有一个非常类似于下面描述的场景:DialogFragment - 在屏幕旋转后保留监听器
建议的解决方案适用于作者,因为他的对话框是从活动中调用的.我的情况完全相同,但我的自定义对话框是从片段而不是活动调用的.(IE Activity-> Fragment-> Dialog)
我实现了相同的解决方案(在调用Fragment中设置onResume中的监听器)但在这种情况下它不起作用.
似乎正在发生的事情是,当屏幕旋转时,Android会杀死Dialog和Fragment.然后按顺序重新创建它们.因此,当我的自定义对话框上调用onCreateDialog时,包含的片段尚未重新创建,因此它为侦听器设置为正和负按钮时为null.
有没有人知道这方面的方法?
如果有人认为有必要,我可以发布代码,但它与链接线程上的代码几乎相同.
更新代码:
public class RecipeDetailEditFragment extends SherlockFragment implements DialogInterface.OnClickListener {
private EditStepFragmentDialog stepDialog;
private Recipe newRecipe; //main data object implements parcelable
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
stepDialog = EditStepFragmentDialog.newInstance(newRecipe);
//I've also tried passing 'this' into the newInstance constructor and
//setting the listener there, but that doesn't work either
}
public void onResume() {
stepDialog.setListener(this);
super.onResume();
}
...
}
public class EditStepFragmentDialog extends DialogFragment {
private DialogInterface.OnClickListener …Run Code Online (Sandbox Code Playgroud) android android-lifecycle android-fragments android-dialogfragment
所以,这个问题非常明显.可自定义的Application对象(一个我申报AndroidManifest.xml)比早期推出的破坏Service,前提是Service在没有另一个进程中启动的?
我的直觉说这是不可能的,因为我们可以通过调用来访问Application对象,而且我在文档中没有看到这样的东西,但却充满了意想不到的有趣行为.ServicegetApplication()Android
我遇到了两种不同的类型,可以根据一些参数来运行我的活动.第一个是savedInstanceState,另一个是getIntent.getExtras()
Q1)所以我不明白的是,一旦我将bundle传递给我的活动然后启动它,它应该有捆绑.但是,如果由于某种原因再次重新创建活动,它应该重新拥有相同的包.(我对吗?)
Q2)基于Q1是真的事实,以及我不能只在活动已经开始时覆盖捆绑的事实,我想如果由于某种原因在我已经开始的Activity中,我想要改变一些params捆绑,我应该创建一些活动字段,并在我的活动生活中使用这些字段.如果由于某种原因重新创建我的活动,则覆盖saveInstanseState以保存新字段.这是真的吗?
Q3)基于以上事实都是正确的事实,在onCreate()中,Android世界中的每个活动都需要像这样开始:
if (savedInstanceState != null) {
mType = savedInstanceState.getInt("some_val1");
mCardId = savedInstanceState.getLong("some_val2");
mQuery = savedInstanceState.getString("some_val3");
mCategory = savedInstanceState.getLong("some_val4");;
} else {
mType = getIntent().getExtras().getInt("some_val1");
mCardId = getIntent().getExtras().getLong("some_val2");
mQuery = getIntent().getExtras().getString("some_val3");
mCategory = getIntent().getExtras().getString("some_val4");
}
Run Code Online (Sandbox Code Playgroud)
Q4)假设onSaveInstanceState被调用并且保存的值与启动活动的原始包(getIntent.getExtras)不同,如果再次重新创建活动,这是否意味着saveInstanceState与getIntent.getExtras()或它们不同现在一样吗?(如果它们是相同的,那么上面代码中的if/else没有真正含义,因为它是相同的!).
Q5)如果我没有覆盖onSaveInstanceState但是当我创建活动时我将它传递给Bundle,这是否意味着如果再次重新创建活动,我可以获得原始包?(我想这个问题会根据其他答案回答)
AdView 是自动绑定到活动生命周期还是必须显式调用pause, resume,destroy事件?它是否取决于 AdView 的大小?我正在使用横幅广告。
我找不到很多其他人这样做的代码示例,主要的 Android 帮助文章也没有提到它(他们只是在 onCreate 中加载广告,不做任何其他事情)。
https://developers.google.com/android/reference/com/google/android/gms/ads/AdView (代码示例包括 pause/resume/destroy 并在方法说明中提到我们“应该调用这些方法”,但是不详述)。
https://developers.google.com/admob/android/banner (没有提到需要暂停/恢复/销毁)。
http://thetechnocafe.com/a-complete-guide-to-integrating-admob-in-your-android-app/ (暂停并销毁代码中的视频广告,但没有提及原因或给出任何解释)
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- app content -->
<com.google.android.gms.ads.AdView
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="@+id/myAdView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-3940256099942544/6300978111">
</com.google.android.gms.ads.AdView>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
public class MainActivity extends AppCompatActivity {
private AdView mAdView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
mAdView = findViewById(R.id.myAdView);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
// do I need this code as well???
@Override
public …Run Code Online (Sandbox Code Playgroud) 我在 Kotlin 的嵌套片段中遇到了一些问题。我用 ViewModel 嵌套了片段。从后退按钮恢复片段后,虽然我的数据没有改变,但再次按下 viewModel LiveData 上的所有观察者触发。
首先我用谷歌搜索并尝试在字段变量中定义观察者并检查它是否已初始化然后不要再次观察它:lateinit var观察者:观察者
fun method(){
if (::observer.isInitialized) return
observer = Observer{ ... }
viewModel.x_live_data.observe(viewLifecycleOwner ,observer)
}
Run Code Online (Sandbox Code Playgroud)
因此,首先进入片段它工作正常,并且在恢复后它不会在没有数据更改的情况下再次触发,但它也不会在数据更改时触发!到底是怎么回事?
我正在从片段启动协程,并且我了解到
lifecycleScope.launch {}
Run Code Online (Sandbox Code Playgroud)
和
viewLifecycleOwner.lifecycleScope.launch {}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下基本上是相同的。
从 Fragment 内部启动协程时,使用其中一个比另一个有好处吗?
android android-lifecycle android-fragments kotlin-coroutines
我认为这对你有用