原文:http://blog.csdn.net/shakespeare001/article/details/51450818

Android开发中Activity和Fragment是非常重要的两个知识点,这里我们就分别归纳一下,在使用Activity和Fragment时需要注意的一些事项,特别是对于Fragment,在对其进行管理时我们要选择好的一些方式。

一、Activity要点

Activity负责展示UI给用户,负责和用户的交互操作。本部分主要对Activity的生命周期、如何保存状态信息、如何讲一个Activity设置成窗口模式、启动模式和完全退出Activity的方式,五部分进行总结。

1、生命周期

Android中是通过Activity栈来管理创建出的Activity,当一个新的Activity被启动时,这个新的Activity就会被加入到Activity栈的栈顶,同时呈现到用户前台,供用户交互,原来的栈顶元素被压入到第二位置,但是它的状态信息还保存着。
掌握Activity生命周期,重点是理解官方给出的生命周期图:
当我们通过context.startActivity()启动一个新的Activity,这个新的Activity被压入到Activity栈顶,来到了屏幕的前台,开始一个完整的Activity生命周期。
--onCreate():只在Activity被刚创建时执行,在onCreate方法中我们初始化我们的Activity,比如,加载布局文件,获取控件(findViewById),绑定触摸事件与用户进行操作等。一般情况下,Activity生命周期的切换不会再触发这个方法的执行,只有当系统极度缺乏内存资源,并且这个Activity没有处在用户前台时,此时该Activity可能被杀死,当再次回到这个Activity,因为这个Activity已被杀死,此时就需要重新创建(就相当于重新startActivity()了),因此会再次进入onCreate进行初始化工作。
--onStart()、onResume():在加载完布局后,系统执行一些内部的启动操作,执行到onResume时,用户可以看到完整的UI界面了,此时Activity处于运行状态。
--onPause():当前的Activity失去了焦点,但依然可以看见,比如当我们点击了一个对话框出来、打开了一个非全屏的Activity、打开了一个透明的Activity,此时原来的Activity就会进入onPause()方法,它依然持有状态信息和内存资源,只有当系统极度缺乏内存资源时,才会杀死处于onPause状态的Activity。
--onStop():当一个Activity被另一个Activity完全覆盖的时候,对用户来说这个Activity不可见了,此时这个Activity就进入onPause状态,它也依然保存着状态信息和资源,但是容易被系统杀死,当内存不是那么充足的时候。
--onDestory():当Activity处于onPause和onStop状态时,系统可能因系统资源吃紧会杀死该Activity,在系统回收该Activity之前,会调用onDestory()方法,在里面进行一些资源的释放工作。onDestory()的调用,可能是用户主动的行为,也可能是因系统资源不足系统需要回收该Activity,在回收前调用。
在Activity被杀死的情况下,当这个Activity再次回到用户前台时,需要重新初始化,即再次进入onCreate,如上图左边的环形图。
在Activity没有被杀死的情况下,处于onPause和onStop状态的Activity再次回到前台时,需要系统还原一些状态,对于onPause状态,由于它处于"比较活跃的一种状态",只需要进入到onResume中由系统设置一些信息即可重新回到前台,对于onStop状态,因为它处于很有可能被销毁的一种状态,部分资源可能丢失,需要先进入onRestart(),然后再次进入onStart()方法,进行回到前台的准备工作。
The visible lifetime(可见的生命周期) :从onStart()到进入onStop()前(即onStart-->onPause),这个Activity都可被用户看见,这期间,不一定处于前台,也不一定能够供用户交互(比如处于onPause状态时)
The foreground lifetime(前台生命周期):从onResume()到进入onPause前,这个期间,Activity处于可以和用户交互时期。这个时期,可能也会频繁在onResume和onPause状态间切换。

2、保存状态信息(推荐在onPause中保存)

从前面生命周期中可以看到,当Activity处于onPause和onStop状态时都有可能被系统回收,因此对于我们该Activity中的一些关键数据最好能够保存下来,当用户再次进入时能够回到原来的状态。官方文档中是推荐我们在onPause()中区保存信息的,比如将数据写入到SharedPreference中。Android还提供了onSaveInstanceState(Bundle)方法来保存数据,通过Bundle来持久化数据。如下例子:
@Overrideprotected void onSaveInstanceState(Bundle outState) {    super.onSaveInstanceState(outState);outState.putString("name","lly");}

当我们这个Activity被销毁而重新创建re-created的时候,通过onCreate(Bundle)中的参数获取到该信息,如下:

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);    if(savedInstanceState != null){        name = savedInstanceState.getString("name");}}

注意:onSaveInstanceState()方法只是在Activity“很容易被销毁的时候调用”,它并不是Activity的生命周期方法,这个调用时机是不确定的,对于点击返回按钮这种主动行为不会去调用这个方法。网上很多说在按下HOME键和旋转屏幕的时候会去调用,但是经过我测试一下,发现不管是我按下HOME键还是旋转屏幕,这个方法都没有被调用。按我理解,这个方法只有在“很容易被销毁的时候调用”,这个尺度应该是系统根据手机具体内存资源情况决定是否调用。因此官方文档中推荐在onPause中进行数据信息的保存操作。(Note that it is important to save persistent data in onPause()instead of onSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation.)

ononSaveInstanceState()方法在Activity、Fragment、Service、各类View中都有提供。其实,默认的ononSaveInstanceState、onRestoreInstanceState()方法的默认实现中,就帮我们保存了系统的一些状态信息,如果我们要保存自己的一些状态信息,就需要重写上面的方法。特别地,在View中,使用ononSaveInstanceState时,对应的这个View一定要在布局文件中定义id,否则没有id,是不会进入到ononSaveInstanceState方法中的。

3、如何将一个Activity设置成窗口的样式

1.在res/values文件夹下的style.xml文件中加入如下代码:
[html] view plaincopy
  1. <style name= "Theme.FloatActivity"  parent= "android:style/Theme.Dialog" >
  2. <!-- float_box为我们定义的窗口背景 ,这个不是必须的-->
  3. <item name="android:windowBackground" > @drawable /float_box</item>
  4. </style>
2.在res/drawable文件夹下新建float_box.xml文件,代码如下:
[html] view plaincopy
  1. <?xml version= "1.0"  encoding= "utf-8" ?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android" >
  3. <solid android:color="#ffffff"  />
  4. <stroke android:width="3dp"  android:color= "#ff000000"  />
  5. <corners android:radius="3dp"  />
  6. <padding android:left="10dp"  android:top= "10dp"  android:right= "10dp"  android:bottom= "10dp"  />
  7. </shape>
3.在AndroidMainifest.xml中Activity的声明中加入
android:theme= "@style/Theme.FloatActivity"
效果如图:
图中显示了一个activity启动另一个activity的效果,布局文件是同一个。其中被启动的activity2是以对话框样式显示,不完全覆盖住启动它的activit1,类似alertDialog。
这与普通的activity不同,默认情况下,activity2会完全遮住activity1,启动activity2后,会调用activity1的onStop方法,而这种以对话框样式显示的activity不会,此时调用的是onPause()。(详见Activity的生命周期)

4、启动Activity的四种模式

我们前面说过,android通过Activity栈来管理启动的Activity,当启动一个Activity时就把它压入到栈顶,其实这只是android的一种默认实现,有时候如果栈中存在相同的Activity,通过设置不同的启动模式,就不一定需要新创建一个Activity了。
Activity有下面四种启动模式:
(1)standard
(2)singleTop
(3)singleTask
(4)singleInstance
通过在AndroidManifest.xml中设置android:lanuchMode,来设置不同的启动方式。
standard
默认的一种启动方式,每次通过Intent打开一个Activity,不管栈中是否已有相同的Activity,都会创建一个新的Activity,并放入到栈顶中。
singleTop
每次通过Intent打开一个启动模式为singleTop的Activity,系统会先判断栈顶中是否有该Activity,如果有,就不会创建新的Acitivity;如果栈顶没有,即使栈中的其他位置上有相同的Activity,系统也会创建一个
新的Activity。和standard模式很相似,只是会对栈顶元素进行判断,解决栈顶多个重复相同的Activity的问题。
当栈顶元素有相同的Activity时,再通过Intent打开同一个Activity不会创建新的对象,但是会调用OnNewIntent(Intent)方法,只有在栈顶有相同的Activity时才会调用这个方法,如果没有相同的,就类似于standard,不会调用OnNewIntent(Intent)方法了。
singleTask
如果栈中已经有该Activity的实例了,不管它在栈中什么位置,都会重用该Activity实例,如果它没在栈顶,此时,就会先把它上面的Activity实例先销毁掉,直到它成为栈顶元素。如果栈中不存在该实例,则会创建一个新的Activity实例放入栈中。当重用Activity时,也会调用OnNewIntent(Intent)方法.
singleInstance
系统会创建出一个新的栈,在这个新的栈中创建该Activity实例,并让多个应用共享改栈中的该Activity实例。一旦改模式的Activity的实例存在于某个栈中,任何应用再激活改Activity时都会重用该栈中的实例,其效果相当于多个应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。 比如,我们一个应用中打开了百度地图,然后在另一个应用中,也准备打开百度地图,此时,它会直接进入到刚才的地图画面,按返回时返回到自己的界面。

5、完全退出程序的几种方法

方案一:定义Activity栈
根据我们上面讲到的,每个Activity都会放入到栈中管理,那我们也可以仿照这个定义一个类似的Activity栈,每打开一个Activity,就把它放入到我们自定义的Activity中,因此我们写一个Activity管理类来管理这些Activity,代码如下:
[java] view plaincopy
  1. /**
  2. * APP管理类
  3. *
  4. */
  5. public class AppManager {
  6. private static Stack<Activity> activityStack;
  7. private static AppManager instance;
  8. private PendingIntent restartIntent;
  9. private AppManager() {
  10. }
  11. /**
  12. * 单一实例
  13. */
  14. public static AppManager getAppManager() {
  15. if (instance == null) {
  16. instance = new AppManager();
  17. }
  18. return instance;
  19. }
  20. /**
  21. * 添加Activity到堆栈
  22. */
  23. public void addActivity(Activity activity) {
  24. if (activityStack == null) {
  25. activityStack = new Stack<Activity>();
  26. }
  27. activityStack.add(activity);
  28. }
  29. /**
  30. * 获取当前Activity(堆栈中最后一个压入的)
  31. */
  32. public Activity currentActivity() {
  33. Activity activity = activityStack.lastElement();
  34. return activity;
  35. }
  36. /**
  37. * 结束当前Activity(堆栈中最后一个压入的)
  38. */
  39. public void finishActivity() {
  40. Activity activity = activityStack.lastElement();
  41. finishActivity(activity);
  42. }
  43. /**
  44. * 结束指定的Activity
  45. */
  46. public void finishActivity(Activity activity) {
  47. if (activity != null) {
  48. activityStack.remove(activity);
  49. activity.finish();
  50. activity = null;
  51. }
  52. }
  53. /**
  54. * 结束指定类名的Activity
  55. */
  56. public void finishActivity(Class<?> cls) {
  57. for (Activity activity : activityStack) {
  58. if (activity.getClass().equals(cls)) {
  59. finishActivity(activity);
  60. }
  61. }
  62. }
  63. /**
  64. * 结束所有Activity
  65. */
  66. public void finishAllActivity() {
  67. for (int i = 0, size = activityStack.size(); i < size; i++) {
  68. if (null != activityStack.get(i)) {
  69. activityStack.get(i).finish();
  70. }
  71. }
  72. activityStack.clear();
  73. }
  74. /**
  75. * 退出应用程序
  76. */
  77. public void exitApp(Context context) {
  78. try {
  79. finishAllActivity();
  80. System.exit(0);
  81. android.os.Process.killProcess(android.os.Process.myPid());
  82. } catch (Exception e) {
  83. }
  84. }
  85. }
方案二:利用广播的方式
这个可以具体看这篇文章:http://blog.csdn.net/way_ping_li/article/details/8031125

二、Fragment

Android是通过FragmentManager来管理Fragment,每次对Fragment进行添加和移除时需要开启事务,通过事务处理这些相应的操作,然后commit事务。

1、添加、移除Fragment的几种方式

在对Fragment进行管理前,需要开启一个事务,如下:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction tx = fm.beginTransaction();

FragmentTransaction下管理Fragment的主要方法有add()、remove()、replace()、hide()、show()、detach()、attach()。
添加Fragment方式一:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.add(R.id.content, new Fragment1(),"Fragment1");
tx.commit();

这里是直接通过add将Fragment1绑定到id为content的View上。
添加Fragment方式二:
        FragmentManager fm = getSupportFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.replace(R.id.content, new Fragment1(),"Fragment1");
tx.commit();
这里使用replace来添加Fragment,replace的作用相当于是remove() + add() 组合后的作用。即使用replace会先移除掉当前id为content上的Fragment,这个被移除掉的Fragment就会被销毁掉(如果当前事务),然后通过add再把新的Fragment添加到View上。
(1)使用replace方式,相当于在对应id为content的FrameLayout上只有一层,那就是上面的Fragment1,通过replace这种方式,会把Fragment的生命周期再走一遍,如果我们的Fragment中有获取数据的操作的话,会频繁的去拉取数据;使用replace,Fragment绑定的视图一定会销毁,Fragment实例不一定会销毁,主要看有没有添加到回退栈。
(2)而通过add方式,我们可以在id为content的FrameLayout上添加多层,也即可以通过多次add来添加多个Fragment到FrameLayout上。这个时候,我们就可以配合hide()、show()方法来不断切换不同的Fragment。在我们通过add方式添加了Fragment到FrameLayout 的View上之后,通过hide()、show()来切换Fragment还有一个优势就是,当一个Fragment重新show展示出来的时候,它原来的数据还保留在该Fragment上,也就是说hide并不会销毁Fragment,只是单纯的隐藏了而已。
推荐方式:
因此,推荐使用add、hide、show的方式管理Fragment。但是这种方式一些情况下也会有一个缺陷就是:可能会造成Fragment重叠
比如底部有四个Tab:tab1,tab2,tab3,tab4,对应的Fragment引用为tab1Fragment,tab2Fragment,tab3Fragment,tab4Fragment,首先通过add将这四个Fragment添加到FragmentManager后,通过hide和show切换不同TAB都可以处于正常情况,当我们切换到tab1时,假设tab1上的Fragment为 tab1Fragment变量指向的(即tab1Fragment=  new Fragment()),这个时候我们按下HOME键,如果长时间没有回到应用或者内存不足了,系统回收了该引用,此时tab1Fragment= null;但是,tab1的Fragment实例其实还是存在与内存中,只是引用被销毁了,这个时候,我们切换到tab2,这个步骤中,我们会把tab1的fragment隐藏掉,然后显示tab2,即如下操作:
tx.hide(tab1Fragment);
tx.show(tab2Fragment);
tx.commit();

但是,因为此时 tab1Fragment = null,引用变量为空,hide操作无法实现隐藏功能,但是又由于tab1上的Fragment实例还处于内存中,因此此时会造成tab2与tab1重叠的现象。再切换到tab1时,因为tab1Fragment = null,此时会再去创建一个新的Fragment,放入到tab1上,导致原来的tab1上的Fragment一直存在与内存中导致重叠,直至它被回收。
造成上述问题的原因还是因为我们无法找到那个实例对象Fragment,因为引用tab1Fragment已经为空了。这个时候,我们在add的时候可以给Fragment绑定一个tag,用它来标识该Fragment,如果引用为空了,再通过tag来找到该Fragment。如下:        
[java] view plaincopy
  1. //在添加Fragment时
  2. FragmentManager fm = getSupportFragmentManager();
  3. FragmentTransaction tx = fm.beginTransaction();
  4. tab1Fragment = new Fragment1();
  5. tx.add(R.id.content, tab1Fragment,"fragment1");
  6. tx.commit();
  7. //在使用时,比如切换到tab2时
  8. if(tab1Fragment != null){
  9. tx.hide(tab1Fragment);
  10. tx.show(tab2Fragment);
  11. tx.commit();
  12. }else{
  13. tab1Fragment = (Fragment1) fm.findFragmentByTag("fragment1");
  14. tx.hide(tab1Fragment);
  15. tx.show(tab2Fragment);
  16. tx.commit();
  17. }
关于上面的缺陷实例,具体可以看这篇文章:http://blog.csdn.net/shimiso/article/details/44677007

2、回退栈

当我们在一个Activity中有多个Fragment进行切换时,我们按下返回键时,会直接退出这个Activity,如果我们想在按下返回键时,退回到上一个显示的Fragment,而不是直接返回,我们就需要使用到回退栈了,类似于系统为每个应用创建的Activity栈一样,每个Activity也维护着一个事务回退栈,在我们通过事务对Fragment进行操作的时候,如果将这个事务添加到回退栈了,这个Fragment的实例就不会被销毁。按返回键时就可以回到这里。如下:
在MainActivity中,
[java] view plaincopy
  1. public class MainActivity extends Activity  {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState)  {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. FragmentManager fm = getSupportFragmentManager();
  7. FragmentTransaction tx = fm.beginTransaction();
  8. tx.add(R.id.content, new Fragment1(),"fragment1");
  9. tx.commit();
  10. }
  11. }
进入Activity时初始化加载第一个Fragment1,这里我们并没有把它加入到回退栈中,这是因为当目前显示的是Fragment1时,按下返回键我们就是需要直接退出,因为这是最初的那个Fragment,如果我们加入到了回退栈,那按下返回键后将是一片空白,再按一次返回键后才会退出这个Activity,这是因为第一次按下返回键时,相当于是将Fragment1从栈中弹出,此时被销毁了,Activity的FrameLayout也就没有了Fragment依附,因此一片空白。
在Fragment1中,有了一个按钮,点击后打开第二个Fragment2,
[java] view plaincopy
  1. public class Fragment1 extends Fragment implements OnClickListener  {
  2. private Button mBtn;
  3. @Override
  4. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  5. Bundle savedInstanceState)  {
  6. View view = inflater.inflate(R.layout.fragment_one, container, false);
  7. mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);
  8. mBtn.setOnClickListener(this);
  9. return view;
  10. }
  11. @Override
  12. public void onClick(View v)  {
  13. Fragment2 fTwo = new Fragment2();
  14. FragmentManager fm = getFragmentManager();
  15. FragmentTransaction tx = fm.beginTransaction();
  16. tx.replace(R.id.content, fTwo, "fragment2");
  17. tx.addToBackStack(null);  //将当前事务添加到回退栈
  18. tx.commit();
  19. }
  20. }
在Fragment2中,
[java] view plaincopy
  1. public class Fragment2 extends Fragment implements OnClickListener {
  2. private Button mBtn ;
  3. @Override
  4. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  5. Bundle savedInstanceState)  {
  6. View view = inflater.inflate(R.layout.fragment_two, container, false);
  7. mBtn = (Button) view.findViewById(R.id.id_fragment_two_btn);
  8. mBtn.setOnClickListener(this);
  9. return view ;
  10. }
  11. @Override
  12. public void onClick(View v)  {  //打开Fragment3
  13. Fragment3 fThree = new Fragment3();
  14. FragmentManager fm = getFragmentManager();
  15. FragmentTransaction tx = fm.beginTransaction();
  16. tx.hide(this);  //隐藏当前显示的Fragment2
  17. tx.add(R.id.content , fThree, "fragment3");  //添加Fragment3
  18. tx.addToBackStack(null);  //将当前事务添加到回退栈
  19. tx.commit();
  20. }
  21. }
在Fragment3中我们只是打印了一些消息,就不再写了。
当当前显示到Fragment3时,我们按下返回键,将会显示出Fragment2出来,继续按下返回键,显示出Fragment1出来,再按下后,直接退出Activity。
因为我们在Fragment1和Fragment2中,在事务提交之前,即tx.commit()之前,我们把当前的事务(用新的Fragment替换当前显示Fragment或者hide当前Fragment)加入到了回退栈,即tx.addToBackStack(null),点击返回键后,就从回退栈中退出栈顶元素,即上一个加入的事务。
上面我们使用了前面介绍的两种添加Fragment的方式,即replace方式和hide()、add()方式,replace方式,Fragment绑定的视图一定会销毁,如果该事务加入到了回退栈,Fragment实例就不会被销毁,只是视图销毁了;而hide()、add()方式隐藏当前Fragment,加入新的Fragment,隐藏的Fragment绑定的视图也不会被销毁。
这里的视图销不销毁,指的是我们的数据有没有被保存下来,如果视图被销毁了,说明重新回到这个Fragment后,会重新进入onCreate及之后的周期方法区创建一个新的视图,这个时候数据肯定就不在了;
如果视图没有被销毁,在重新回到这个Fragment时,原来的输入数据还在,没有丢失。
当然,在Fragment里面也有onSaveInstanceState(Bundle)方法,可以通过这个来保存数据,然后再onCreate或其他方法里面获取到数据来解决数据丢失的问题。

3、与Activity通信

因为Fragment依附于Activity,Activity与Fragment通信,可以有以下几种办法:

(1)如果你Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法

(2)如果Activity中没有保存任何Fragment的引用,那么没关系,每个Fragment都有一个唯一的TAG或者ID,可以通过getSupportFragmentManager().findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。

(3)在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。

最新Activity与Fragment完全理解相关推荐

  1. 安卓APP_ Fragment(2)—— Activity与Fragment的通信

    摘自:安卓APP_ Fragment(2)-- Activity与Fragment的通信 作者:丶PURSUING 发布时间: 2021-04-16 17:23:44 网址:https://blog. ...

  2. android fragmentactivity fragment,Android:Activity与Fragment通信(99%)完美解决方案

    前言 最近一直在想着能否有一种更好的方案来解决:Android中Activity与Fragment之间通信的问题,什么叫更好呢,就是能让Fragment的复用性高,性能还有好(不用反射),代码还要好维 ...

  3. 适合初学者入门的项目,通过对 Kotlin 的系统运用,实现的一个功能完备符合主流市场标准 App。包含知识点(MVVM 开发架构、单 Activity 多 Fragment 项目设计、暗夜模式、屏幕

    fragmject 项目地址:miaowmiaow/fragmject 简介: 适合初学者入门的项目,通过对 Kotlin 的系统运用,实现的一个功能完备符合主流市场标准 App.包含知识点(MVVM ...

  4. Android开发帮助技巧(适用于入门)(第一部分-高效地构建项目的准备工作和Activity与Fragment的交互介绍)

    平台: windows11 Android Studio 4.2.2 Build #AI-202.7660.26.42.7486908, built on June 24, 2021 Runtime ...

  5. activity改成fragment android,Activity转换为Fragment

    Activity中加载不同的fragment  / Fragment中加载不同的fragment 主Activity中加载(切换)多个fragment(也可以理解为activity 尽管Fragmen ...

  6. Lifecycle Activity和Fragment生命周期感知组件 LifecycleObserver MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. Activity与Fragment的生命周期详解

    在安卓中Activity与Fragment是非常相似的两个类,它们各自都拥有自己的生命周期,且都可以用来显示布局文件中的视图.其中Activity是通过setContenView()显示视图,而Fra ...

  8. activity中fragment 返回键不退出_优雅地处理加载中(loading),重试(retry)和无数据(empty)等...

    LoadSir是一个高效易用,低碳环保,扩展性良好的加载反馈页管理框架,在加载网络或其他数据时候,根据需求切换状态页面,可添加自定义状态页面,如加载中,加载失败,无数据,网络超时,占位图,登录失效等常 ...

  9. 多个Activity与Fragment之间的数据传递

    多个Activity与Fragment之间数据传递 问题描述 解决思路 具体解决 bug de到亲妈落泪. 问题描述 首先展示个人问题的整体框架: ActivityA:主页面,有一个PageView控 ...

  10. Android 如何快速定位当前页面是哪个Activity or Fragment

    在日常需求开发中,经常碰到不太熟悉的模块,如何快速定位相应页面对应的Activity/Fragment ? (1)查看当前Activity  :adb shell "dumpsys wind ...

最新文章

  1. HTML5实践 -- 使用css装饰你的图片画廊 - part2
  2. Eclipse启动时报错
  3. Springboot集成websocket实例
  4. python翻译程序-Python桌面应用案例:TXT文档翻译工具(源代码)
  5. LOOPS HDU - 3853 (概率dp):(希望通过该文章梳理自己的式子推导)
  6. 计算机考试一级考试基础知识,2016计算机一级考试msoffice基础知识
  7. jquery、javascript实现(get、post两种方式)跨域解决方法
  8. Android应用程序消息处理机制
  9. eclipse集成weblogic开发环境的搭建
  10. 【UE4游戏开发】安装UE4时报SU-PQR1603错误的解决方法
  11. Python之魔法方法详解
  12. c++获取数组长度查找算法_在C ++中查找数组长度
  13. 吴恩达机器学习课后作业
  14. 【CyberSecurityLearning 66】提权
  15. 提高电脑开机速度的方法
  16. 嵌入式linux调节lcd背光,背光调节的软件设计 - 基于嵌入式Linux的LCD背光调节及驱动实现...
  17. BUU-CRYPTO1密码学小白 25道入门题 详细解题思路
  18. 升级啦!二维码签到适用PC+andriod+IOS-PHP源码-开源代码
  19. vue视频播放插件vue-video-player
  20. 博客中的动态图片如何制作

热门文章

  1. php 获取文件加的名称
  2. 营销工作的七项核心能力
  3. java异步文件读写文件,Java AsynchronousFileChannel和Future读取文件
  4. 南阳oj-----D的小L(algorithm全排列用法)
  5. 问道手游服务器维护,问道手游2021年5月20日维护公告_问道手游2021年5月20日更新了什么_玩游戏网...
  6. java实验十三io_Java语言基础13—IO
  7. 虚拟机与ubuntu(二):连接访问
  8. maya前台渲染_maya前台渲染MEL
  9. 建模步骤_SolidWorks建模气球球拖,有步骤,新手都在找的练习题
  10. ai快捷键常用表_掌握这些AI常用快捷键和小技巧,提高速度