Android知识总结

  1. 打开一个App, 从主页跳转到其深层子页面,按HOME键回到桌面,再次打开,怎么才能使再次打开看到的是主页面?
    (注:这个过程app并没有被回收销毁)

    答:这个是通过配置主页Activity在Manifest里面的标签属性即可实现

        <activity android:name=".MainActivity"
           android:clearTaskOnLaunch="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />
    
               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
    

    给主Activity添加属性android:clearTaskOnLaunch = "true"即可实现

  2. 一个Activity的启动模式是singleTop,如何实现像singleTask模式的启动效果,即如果这个Activity不在这个任务栈中,创建一个新的实例,如果在这个任务栈中,无论是否在栈顶,都复用之前的实例,不再重新创建了,如果不在栈顶,则,把它上面的Activity出栈,把此Activity置于栈顶? (注:不要改变这个Activity启动模式为singleTask的前提下)

    答:在启动此Activity的时候,为intent添加一个FLAG为 Intent.FLAG_ACTIVITY_CLEAR_TOP 即可。

    Intent i = new Intent(this,SecondActivity.class);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
    

    下面是Android源码对 Intent.FLAG_ACTIVITY_CLEAR_TOP 的解释

     If set, and the activity being launched is already running in the
     current task, then instead of launching a new instance of that activity,
     all of the other activities on top of it will be closed and this Intent
     will be delivered to the (now on top) old activity as a new Intent.
    
     For example, consider a task consisting of the activities: A, B, C, D.
     If D calls startActivity() with an Intent that resolves to the component
     of activity B, then C and D will be finished and B receive the given
     Intent, resulting in the stack now being: A, B.
     
     The currently running instance of activity B in the above example will
     either receive the new intent you are starting here in its
     onNewIntent() method, or be itself finished and restarted with the
     new intent.  If it has declared its launch mode to be "multiple" (the
     default) and you have not set {@link #FLAG_ACTIVITY_SINGLE_TOP} in
     the same intent, then it will be finished and re-created; for all other
     launch modes or if {@link #FLAG_ACTIVITY_SINGLE_TOP} is set then this
     Intent will be delivered to the current instance's onNewIntent().
     
     This launch mode can also be used to good effect in conjunction with
     {@link #FLAG_ACTIVITY_NEW_TASK}: if used to start the root activity
     of a task, it will bring any currently running instance of that task
     to the foreground, and then clear it to its root state.  This is
     especially useful, for example, when launching an activity from the
     notification manager.
    

    如果设置这个属性,并且这个activity已经在当前任务栈中运行,那么就不会再在这个任务栈中为这
    个activity创建一个新的实例,而是复用这个存在的实例,并且此Activity上面所有其他的activities
    都会被出栈,这个intent会被传递给这个被复用的activity实例。

    例如:一个任务栈中有A、B、C、D四个activity,如果D通过包含此FLAG的Intent调起B,那么C、D将会被
    关闭掉,B会接收到这个intent,此时任务栈中只有A、B两个activity了

    在上面的例子中,这个正在运行的Activity B 将会通过onNewIntent()方法接收intent或者他自动关闭再重新启动。
    如果Activity B的启动模式是默认的,且设置的不是FLAG_ACTIVITY_SINGLE_TOP,那么ActivityB会自动销毁并且重新创建,
    如果设置的是其他启动模式或者是singleTop的话,Activity B将不会销毁重建,而是被复用,通过onNewIntent();接收传递过来的intent。

    这个启动模式(Intent.FLAG_ACTIVITY_CLEAR_TOP)和(FLAG_ACTIVITY_NEW_TASK)一起使用将会起到很好的效果,
    如果你想启动某个根Activity,那么它会把包含这个根Activity的任务栈放到前台运行,并且会把这个任务栈中的根Activity之上的其他Activity都出栈,把此根Activity置于栈顶。这是非常有用的,例如通过通知管理器启动Activity

  3. 如果连续多次启动某个IntentService,会为这个IntentService创建多个实例吗,IntentService里面的耗时操作是各自执行吗?

    答:首先看一下IntentService的官方解释

      IntentService is a base class for {@link Service}s that handle asynchronous
      requests (expressed as {@link Intent}s) on demand.  Clients send requests
      through {@link android.content.Context#startService(Intent)} calls; the
      service is started as needed, handles each Intent in turn using a worker
      thread, and stops itself when it runs out of work.
     
      This "work queue processor" pattern is commonly used to offload tasks
      from an application's main thread.  The IntentService class exists to
      simplify this pattern and take care of the mechanics.  To use it, extend
      IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService
      will receive the Intents, launch a worker thread, and stop the service as
      appropriate.
     
      All requests are handled on a single worker thread -- they may take as
      long as necessary (and will not block the application's main loop), but
      only one request will be processed at a time.
    

    意思就是IntentService可以处理异步请求,客户端通过startService(Intent)发来请求,
    IntentService相应的就会启动,每个intent都会通过一个工作线程处理,并且任务执行
    完之后,会自动结束掉

    这种工作队列处理器模式主要是用来分担主线程的任务,IntentService的存在简化了
    这种模式并且它比较关注的是运行机制。可以通过继承IntentService并且实现onHandleIntent(Intent)
    来使用它。IntentService收到Intent之后,会开启一个工作线程,并且会在合适的时候自动关闭。

    所有的请求都会交给一个异步线程处理,每个任务都会花费掉他们所需要长的时间来处理,但是不会阻塞
    主线程,但是每次只能处理一个任务。

    下面简单看一下IntentService的源码:

     @Override
     public void onCreate() {
         // TODO: It would be nice to have an option to hold a partial wakelock
         // during processing, and to have a static startService(Context, Intent)
         // method that would launch the service & hand off a wakelock.
    
         super.onCreate();
         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
         thread.start();
    
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper);
      }
    

    首先IntentService的onCreate()方法创建了一个HandlerThread并且启动了它,并且把它持有的Looper给了
    mServiceHandler,那么mServiceHandler处理的就是这个子线程里面的消息了 并且无论startService多少次,IntentServcie的onCreate()方法就执行一次,所以即便是有很多个任务,也只会
    只有一个工作线程来处理。

     @Override
     public void onStart(@Nullable Intent intent, int startId) {
         Message msg = mServiceHandler.obtainMessage();
         msg.arg1 = startId;
         msg.obj = intent;
         mServiceHandler.sendMessage(msg);
     }
    

    再来看IntentService的onStart()方法,它得到了一个message对象,并且把intent存储在里面,通过
    mServiceHandler发送了出去,那么这个message对象最终会被存储到子线程的Queue中去,然后再通过
    子线程的Looper.loop()方法取出,给mServiceHandler.handleMessage(Message)处理,这样对Intent的处理
    就从主线程转移到了子线程,并且每调用startService(Intent)一次,onStart()方法就执行一次,这样
    接收到的Intent就会一次通过mServiceHandler发送到消息队列里面等待处理。

     private final class ServiceHandler extends Handler {
         public ServiceHandler(Looper looper) {
             super(looper);
         }
    
         @Override
         public void handleMessage(Message msg) {
             onHandleIntent((Intent)msg.obj);
             stopSelf(msg.arg1);
         }
     }
     
     @WorkerThread
     protected abstract void onHandleIntent(@Nullable Intent intent);
    

    如上所说:最终Intent通过mServiceHandler的handleMessage(Message)方法传给了onHandleIntent(Intent)
    来处理了,此时已经是在异步线程中了,如果有多个任务,都会存放到消息队列里面去,等待处理,但是始终只有一个IntentServide实例,并且只有一个子线程来处理任务。

  4. ListView的优化
    (1). 复用convertView,如果convertView为null,就创建一个convertView,如果不为null,则复用convertView
    (2). 使用viewHolder。使用viewHolder可以使View内的组件随着View的复用而复用,通过ViewHolder复用View内的组件的方法是:view.setTag(viewHolder)和view.getTag()。
    (3).分页加载数据和分批加载数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值