精华内容
下载资源
问答
  • Android 线程

    2021-06-02 14:19:22
    假如不使用线程池,有可能造成系统创立大量同类线程而导致消耗完内存或者者“过度切换“的问题,归纳总结就是:重用存在的线程,减少对象创立、消亡的开销,性能佳。可有效控制最大并发线程数,提高系统资源的使用率...

    1、线程池的好处?四种线程池的使用场景,线程池的几个参数的了解?

    使用线程池的好处在于,是可以减少在创立和销毁线程上所花的时间,以及系统资源的开销,处理资源不足的问题。假如不使用线程池,有可能造成系统创立大量同类线程而导致消耗完内存或者者“过度切换“的问题,归纳总结就是:重用存在的线程,减少对象创立、消亡的开销,性能佳。

    可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

    提供定时执行、定期执行、单线程、并发数控制等功能。

    Andorid中的线程池都是直接或者间接通过配置ThreeadPoolExecutor来实现不同特性线程池。Android中最常见的类具备不同特性的线程池分别为:newCachedThreadPool:只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创立新线程,否则会利用空闲线程(60s空闲时间,过了就会被回收,所以线程池中有0个线程的可能)来解决任务。

    优点:任何任务都会被立即执行(任务队列SynchonousQue相当于一个空集合);比较适合执行大量的耗时较少的任务。

    newFixedThreadPool:只有核心线程,并且数量固定的,所有线程都活动时,由于队列没有限制大小,新任务会等待执行,当线程池空闲时,不会释放工作线程,还会占用肯定的系统资源。

    优点:更快的响应外界请求

    newScheduledThreadPool:核心线程数固定,非核心线程(闲置没活干会被立即回收)没有限制。

    优点:执行定时任务以及固定周期的重复任务

    newSingleThreadExecutor:

    只有一个核心线程,确保所有任务都在同一线程中按序完成

    优点:不需要解决线程同步的问题

    通过源码可以理解到上面四种线程池实际还是利用ThreadPoolExecutor类实现的:

    36819181e1d4ea2359014d86569c4919.png

    2、Android中还理解哪些方便线程切换的类?

    AsyncTask:底层封装了线程池和Handler,便于执行后端任务以及在子线程中进行UI操作。

    HandlerThread:一种具备消息循环的线程,其内部可使用Handler

    IntentService:是一种异步、会自动中止的服务,内部采用HandlerThread、

    3、讲讲AsyncTask的原理

    AsyncTask中有两个线程池(SerialExecutor

    和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler),其中线程池SerialExecutor用于任务的排队,而线程池THREAD_POOL_EXECUTOR用于正真地执行任务,InternalHandler用于将执行环境从线程池切换到主线程。

    SHandle是一个静态的Handler对象,为了能够将执行环境切换到主线程,这就要求sHandler这个对象必需在主线程创立。因为静态成员会在加载类的时候进行初始化,因而这就变相要求AsyncTask的类必需在主线程中加载,否则同一个进中的AsyncTask都将无法正常工作。

    4、IntentService有什么用?

    IntentService可用于执行后端耗时的任务,当任务执行完成后会自动中止,同时因为IntentService是服务的起因,不同于普通Service,IntentService可自动创立子线程来执行任务,这导致它的优先级比单纯的线程要高,不容易被系统杀死,所以IntentService比较适合执行少量高优先级的后端任务。

    5、直接在Activity中创立一个thread跟在service中创立一个thread之间的区别?

    在Activity中被创立:该Thread的就是为这个Activity服务的,完成这个特定的Activity交代的任务,主动通知该Activity少量消息和时间,Activity销毁后该Thread也没有存活的意义了。

    在Service中被创立:这是保证最长生命周期的Thread的唯一方式,只需整个Service不退出,Thread即可以一直在后端执行,一般在Service的onCreate()中创立,在onDestory()中销毁。所以,在Service中创立的Thread,适合长期执行少量独立于APP的后端任务,比较常见的就是:在Service中保持与服务端的长连接。

    6、ThreadPollExecutor的工作策略?

    ThreadPoolExecutor执行任务时会遵循如下规则假如线程池中的线程数量未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。

    假如线程池中的线程数量已经到达或者者超过核心线程的数量,那么任务会被插入任务队列中排队等待执行。

    假如在第2点无法将任务插入到任务队列中,这往往是因为任务队列已满,这个时候假如在线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务。

    假如第3点中线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者。

    7、Handler、Thred和HandlerThread的差别?Handler:在android中负责发送和解决消息,通过它可以实现其余支线线程与主线程之间的消息通讯。

    Thread:Java进程中执行运算的最小单位,亦即执行解决机调度的基本单位。某一进程中一路单独运行的程序。

    HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对java中Thread进行任何封装,而是提供一个继承自Thread的类,这个类对java的Thread做了很多便利的封装。HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它在内部直接实现了Looper的实现,这是Handler消息机制必不可少的。

    有了自己的looper,可以让我们在自己的线程中分发和解决消息。假如不用HandlerThread的话,需要手动去调用Looper.prepare()Looper.loop()这些方法。

    8、ThreadLocal的原理

    ThreadLocal是一个关于创立线程局部变量的类。使用场景如下所示:实现单个线程单例以及单个线程上下文消息存储,比方交易id等。

    实现线程安全,非线程安全对象使用ThreadLocal之后就会变得线程安全。由于每个线程都会有一个对应的实例。承载少量线程相关的数据,避免在方法中来回传递参数。

    当需要使用多线程时,有个变量凑巧不需要共享,此时就不必使用sychronzid这么麻烦的关键字来锁住,每个线程都相当于在堆内存中开拓一个空间,线程中带有对共享变量的缓冲区,通过缓冲区将堆内存中的共享变量进行读取和操作,ThreadLocal相当于线程内的内存,一个局部变量。每次可以对线程自身的数据读取和操作,并不需要通过缓冲区与主内存中的变量进行交互。并不会像synchronized那样修改主内存的数据,再将主内存的数据复制到线程内的工作内存。ThreadLocal可以让线程独占资源,存储于线程内部,避免线程堵塞造成CPU吞吐下降。

    在每个Thread中包含一个ThreadLocalMap,ThreadLocalMap的key是ThreadLocal的对象,value是独享数据。

    9、多线程能否肯定会高效(优缺点)

    多线程的优点方便高效的内存共享 - 多进程内存共享比较不便,且会抵消掉多进程编程的好处

    较轻的上下文切换开销 - 不用切换地址空间,不用更改CR3寄存器,不用清空TLB

    线程上的任务执行完后自动销毁

    多线程的缺点:开启线程需要占用肯定的内存空间(默认情况下,每个线程都占512KB)

    假如开启大量的线程,会占用大量的内存空间,降低程序的性能

    线程越多,cpu在调用线程上的开销就越大

    程序设计更加复杂,比方线程间的通信、多线程的数据共享

    综合得出,多线程不肯定能提高效率,在内存空间紧张的情况下反而是一种复旦,因而在日常反开发中,应尽量:不要频繁创立,销毁线程,使用线程池

    减少线程间同步和通信(最为关键)

    避免需要频繁共享写的数据

    正当共享数据结构,避免共享(false sharing)

    使用非阻塞数据结构、算法

    避免可能产生大量缺页异常,尽量使用Huge Page

    可以的话使用客户态轻量级线程代替内核线程

    10、多线程中,让你做一个单例,你会怎样做

    多线程中建立单例模式考虑的因素有很多,比方线程安全-推迟加载-代码安全:如防止序列化攻击,防止反射攻击()防止反射进行私有方法调用-性能因素

    实现方法有多重,饿汉,懒汉(线程安全,现场非安全),多重检查(DCL),内部类,以及枚举

    972c806ba656d14210d30826a0c26660.png

    11、除了notify还有什么方式可以唤醒线程当一个拥有Object锁的线程调用wait()方法时,就会使当前线程加入object。wait等待队列中,并且释放当前占用的Object锁,这样其余线程就会有机会获取这个Object锁,取得Objecet锁的线程调用notify()方法,就能Object.wait等待队列中随机唤醒一个线程(该唤醒是随机的与加入的顺序无关,优先级高的被唤醒概率会高)

    假如调用notifyAll()方法就唤醒一律的线程。注意:调用notify()方法后并不会立即释放object锁,会等待该线程执行完毕后释放Objecet锁。

    12、什么事ANR?什么情况会出现ANR?如何避免?在不看代码的情况下如何快速定位出现ANR问题所在?ANR(Application Not Responding,应用无响应):当操作在一段时间内系统无法解决时,会在系统层面会弹出ANR对话框

    产生ANR可能是由于5s内无响应客户输入时间、10s内未结束BroadcastReceiver、20s内未结束Service

    想要避免ANR就不要在主线程做耗时操作,而是通过开子线程,方法比方继承Thread或者实现Runnable接口、使用AsyncTask、IntentService、HandlerThread等

    展开全文
  • Android线程间通信机制

    2021-02-27 08:58:57
    先完整叙述一遍我们要讲解的问题:Android线程间通信机制 一、两个关键词,两点疑问## 在"Android线程间通信机制"这句话中,有两个关键词需要我们需要搞清,一个是线程间,一个是通信,当我一开始深入思考这两个...

    讲解Handler机制的博文很多,我也看了很多,但说实话,在我对Handler几乎不怎么了解的情况下,每一篇文章我都没太看懂,看完之后脑子里还是充满了疑问。究其原因,是因为几乎每一篇文章一上来就开始深入Handler源码,使得在一些宏观的问题上还是充满疑问,如果你从来没接触过Handler,对一些基础的问题还充满疑问,那深入源码去探究根源肯定会有些吃力。

    下面,我就从一个初学者思考的角度,来讲一讲Handler运行机制,准确的说应该是Android消息处理机制,因为虽然说Handler很重要,它最多被提到,但其它的几个角色也是各司其职,一个都不能少。

    先完整叙述一遍我们要讲解的问题:Android线程间通信机制

    一、两个关键词,两点疑问##

    在"Android线程间通信机制"这句话中,有两个关键词需要我们需要搞清,一个是线程间,一个是通信,当我一开始深入思考这两个关键词的时候,心中就有了些疑问,可是很多博文也没有讲到,这也是导致我一开始看别人写的文章就稀里糊涂的原因,发现文章看完,疑惑还在,而疑惑就来源于这两个关键词。

    1、线程间###

    我们知道,Android应用程序的一个进程当中可能会存在多个线程,但它们的地位是不一样的,分为两种:有一个是主线程(也叫UI线程),其它的都是普通的工作线程。那么线程间通信就会分为两种情况:主线程和工作线程通信;工作线程和工作线程通信。

    之所以要把这两种情况给提出来,是因为基本上所有的文章都是上来直接讲主线程和普通工作线程之间的通信机制,我还没有看到过讲两个普通工作线程通信的,这就让我有了一个疑问,Q1:难道线程间通信只能发生在主线程和工作线程之间吗?而没有两个工作线程通信的情况吗?

    答案是可以的,可能是因为主线程和工作线程通信的情况最常见,例如工作线程向主线程发送消息进行更新UI的操作,而两个工作线程通信的情况比较少见吧(我也是猜测,毕竟我的开发经验太有限)。虽然主线程和普通工作线程地位不同,但只要使用“线程间通信机制”(我们下面要讲的),线程间都是可以互相通信的。相信大家看完文章,不用解释就自然明白了。

    2、通信###

    通信是一个过程,但这个表达很模糊,不够具体,我们把它具体描述应该是:发送消息 + 接收消息 + 处理消息,这样一来定义就清晰了一些。如果我们把这个过程想到这儿,看着好像也明白了,不就那么个过程嘛。但如果大家再多想一步,仔细思考下这个过程,就会心生疑问,至少我当时就有这个疑问,是什么呢,大家先看两张图,是我画的两种通信方式的模型,下面我会解释。

    7657f541c461

    线程间通信.模型猜想一

    我们知道两个线程通信是使用Handler的,这个模型的意思是:我们使用一个Handler进行通信,线程A和线程B都可以发送消息给对方、接收对方传来的消息以及进行消息处理。

    7657f541c461

    线程间通信.模型猜想二

    这个模型的意思是:我们使用一个Handler进行通信,线程A和线程B之间,只有一个可以接收消息并处理,另一个只能够发送。

    那么我的疑问就是,Q2:当我们使用一个Handler进行线程间通信时,到底这两个模型,哪个是正确的?答案是第二个,解释在后面,或许当你看完,也不需要我解释了。

    下面开始正式讲解。

    二、消息处理中的几大角色##

    先给出一张图,这张图是我从别人的博文中看见的,画的不错,我直接拿过来用了,在文末有参考链接。

    7657f541c461

    Android线程间通信流程图

    Message:

    线程间通信就是在传递消息,Message就是消息的载体。常用的有四个字段:arg1,arg2,what,obj。obj可以携带Object对象,其余三个可以携带整形数据。

    MessageQueue:

    MessageQueue是消息队列,它主要用于存放所有通过Handler发送的消息(也就是一个个Message),这部分的消息会一直存在于消息队列中,等待被处理。每个线程中只会有一个MessageQueue对象。

    Looper:

    每个线程通过Handler发送的消息都保存在,MessageQueue中,Looper通过调用loop()的方法,就会进入到一个无限循环当中,然后每当发现Message Queue中存在一条消息,就会将它取出,并传递到Handler的handleMessage()方法中。每个线程中只会有一个Looper对象。

    Handler:

    它主要用于发送和处理消息的发送消息,一般使用sendMessage()方法,还有其他的一系列sendXXX的方法,但最终都是调用了sendMessageAtTime()方法,除了sendMessageAtFrontOfQueue()这个方法。你只要在Looper线程(就是实现了Looper的线程)构建Handler类,那么这个Handler实例就获取该Looper线程MessageQueue实例的引用,Handler 在sendMessage()的时候就通过这个引用往消息队列里插入新消息。

    ThreadLocal:

    这个类我也没太搞懂,不过参考别人的文章有如下一个解释,可以先暂时这样理解:线程本地存储区(Thread Local Storage,简称为TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。MessageQueue对象,和Looper对象在每个线程中都只会有一个对象,怎么能保证它只有一个对象,就通过ThreadLocal来保存

    三、创建Handler的两种方式##

    Handler的创建方式有两种:一个是在主线程中创建,一个是在普通工作线程中创建,两种创建方法是不一样的。Handler在哪个线程中创建,那该线程就负责接收和处理消息,其它的线程只能发送消息。为什么?请往下看。

    1、在主线程中使用Handler###

    在主线程中使用Handler的示例:

    public class TestHandlerActivity extends AppCompatActivity {

    private static final String TAG = "TestHandlerActivity";

    private Handler mHandler = new Handler(){

    @Override

    public void handleMessage(Message msg) {

    super.handleMessage(msg);

    //获得刚才发送的Message对象,然后在这里进行UI操作

    Log.e(TAG,"------------> msg.what = " + msg.what);

    }

    };

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_handler_test);

    initData();

    }

    private void initData() {

    //开启一个线程模拟处理耗时的操作

    new Thread(new Runnable() {

    @Override

    public void run() {

    SystemClock.sleep(2000);

    //通过Handler发送一个消息切换回主线程(mHandler所在的线程)

    mHandler.sendEmptyMessage(0);

    }

    }).start();

    }

    大家如果使用过Handler,这个应该是最常见的了,也是使用最简单的。只需在主线程创建一个handler对象,在子线程通过在主线程创建的handler对象发送Message,在handleMessage()方法中接受这个Message对象进行处理。通过handler很容易的从子线程切换回主线程了。

    2、在普通工作线程中使用Handler###

    我们下面再看一下,在普通工作线程中应该如何使用Handler:

    public class TestHandlerActivity extends AppCompatActivity {

    private static final String TAG = "TestHandlerActivity";

    //主线程的Handler

    private Handler mHandler = new Handler(){

    @Override

    public void handleMessage(Message msg) {

    super.handleMessage(msg);

    //获得刚才发送的Message对象,然后在这里进行UI操作

    Log.e(TAG,"------------> msg.what = " + msg.what);

    }

    };

    //子线程中的Handler

    private Handler mHandlerThread = null;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_handler_test);

    initData();

    }

    private void initData() {

    //开启一个线程模拟处理耗时的操作

    new Thread(new Runnable() {

    @Override

    public void run() {

    SystemClock.sleep(2000);

    //通过Handler发送一个消息切换回主线程(mHandler所在的线程)

    mHandler.sendEmptyMessage(0);

    //调用Looper.prepare()方法

    Looper.prepare();

    mHandlerThread = new Handler(){

    @Override

    public void handleMessage(Message msg) {

    super.handleMessage(msg);

    Log.e("sub thread","---------> msg.what = " + msg.what);

    }

    };

    mHandlerThread.sendEmptyMessage(1);

    //调用Looper.loop()方法

    Looper.loop();

    }

    }).start();

    }

    与在主线程中创建的方式不同,在工作线程中创建的代码中,我们的Handler是在Looper.prepare()和Looper.loop()中间创建的,那这两行代码是做什么用的呢?我们看下源码:

    public final class Looper {

    …………

    private static void prepare(boolean quitAllowed) {

    //如果线程的TLS已有数据,则会抛出异常,一个线程只能有一个Looper,prepare不能重复调用。

    if (sThreadLocal.get() != null) {

    throw new RuntimeException("Only one Looper may be created per thread");

    }

    //往线程的TLS插入数据,简单理解相当于map.put(Thread.currentThread(),new Looper(quitAllowed));

    sThreadLocal.set(new Looper(quitAllowed));

    }

    …………

    }

    在这里可以看出,sThreadLocal对象保存了一个Looper对象,首先判断是否已经存在Looper对象了,以防止被调用两次。sThreadLocal对象是ThreadLocal类型,因此保证了每个线程中只有一个Looper对象。Looper对象在创建时做了什么呢,我们进入看看,如下:

    private Looper(boolean quitAllowed) {

    mQueue = new MessageQueue(quitAllowed);

    mThread = Thread.currentThread();

    }

    可以看出,这里在Looper构造函数中创建出了一个MessageQueue对象和保存了当前线程。从上面可以看出一个线程中只有一个Looper对象,而Message Queue对象是在Looper构造函数创建出来的,因此每一个线程也只会有一个MessageQueue对象。

    所以,当Looper.prepare()执行完了之后,普通的工作线程就变成了Looper线程,该线程就可以接收并处理消息了。如图:

    7657f541c461

    而Looper.loop()方法就是进入一个无限循环,不断的从MessageQueue当中获取消息,当没有消息时就阻塞在那里,这里不再详解。

    3、梳理一下###

    从我们刚才的讲解可以明白:只有实现了Looper和MessageQueue的线程,才能够处理消息,否则一个线程都没有MessageQueue,它又哪来的消息可处理呢?没有Looper,谁来取消息呢?它俩是一套的。

    因此,Handler 对象在哪个线程下构建(Handler的构造函数在哪个线程下调用),那么Handler 就会持有这个线程的Looper引用和这个线程的消息队列的引用。因为持有这个线程的消息队列的引用,意味着这个Handler对象可以在任意其他线程给该线程的消息队列添加消息,也意味着Handler的handlerMessage 肯定也是在该线程执行的。如果该线程不是Looper线程,在这个线程new Handler 就会报错!

    还记得我们刚开始提到的那个线程间通信的简单模型吗,就是下面这个:

    7657f541c461

    因为我们只创建了一个Handler,所以它必定持有某个线程(这里是线程B)的Looper引用和这个线程的消息队列的引用,也就只能在这一个线程中接收和处理消息,其它的只能发送消息。若想实现双向的通信,那就必须在令一个线程当中也创建Looper,并在该线程下再创建一个Handler。

    4、一点疑问###

    我们刚才讲了两种使用Handler的方式,一个是在主线程当中,一个是在其它的普通线程当中。而两种方式的不同就在于:在主线程当中创建Handler,并没有调用Looper.prepare()和Looper.loop()方法,也就是我们没有在主线程中创建Looper。那你可能就会问了,为什么主线程中没有创建Looper,它却可以用来处理消息。为什么?

    因为系统在启动之时,已经帮我们创建好了。也就是说:在任何进程下使用Handler来处理消息,都必须要先创建Looper,在创建Looper的过程中同时也就创建了MessageQueue,否则无法处理消息。之所以会存在两种创建方式,就是因为主线程已经在开始的时候帮我们都准备好了Looper,不用我们手动调用Looper.prepare()和Looper.loop()了。

    那系统是怎么做的呢?这个内容很多博文已经讲了,我会放上我参考的两个讲的比较好的文章在下面,大家感兴趣可以看看。

    完。

    展开全文
  • 1.runOnUiThread(Runnable) 在子线程中直接使用该方法,可以更新UIrunOnUiThread(new Runnable(){//更新UI@Overridepublic void run() {publish_time.setText("更新失败");}});2.View.postDelay(Runnable , long)/...

    1.runOnUiThread(Runnable)              在子线程中直接使用该方法,可以更新UI

    runOnUiThread(new Runnable(){//更新UI

    @Override

    public void run() {

    publish_time.setText("更新失败");

    }

    });

    2.View.postDelay(Runnable , long)/new Handler().postDelayed(Runnable)

    在需要更新UI的地方调用该方法,Runnable对象的方法里,直接操作UI;long是指延迟多少秒

    //延迟一秒钟出现

    new Handler().postDelayed(new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    notify_view_text.setText(String.format(getString(R.string.ss_pattern_update), 10));

    notify_view.setVisibility(View.VISIBLE);

    //延迟两秒钟消失

    new Handler().postDelayed(new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    notify_view.setVisibility(View.GONE);

    }

    }, 2000);

    }

    }, 1000);

    3.使用Handler

    4.使用AsyncTask

    展开全文
  • 线程安全的定义线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且...Android的单线程模型当一个程序第一次启动的时...

    线程安全的定义

    线程安全:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的,或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题 。

    Android的单线程模型

    当一个程序第一次启动的时候,Android会启动一个LINUX进程和一个主线程。默认的情况下,所有该程序的组件都将在该进程和线程中运行 。主线程(Main Thread)主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事 件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

    系统不会为每个组件单独创建线程,在同一个进程里的UI组件都会在UI线程里实例化,系统对每一个组件的调用都从UI线程分发出去。结果就是,响应系统回调的方法(比如响应用户动作的onKeyDown()和各种生命周期回调)永远都是在UI线程里运行。

    UI线程才能与Android UI工具包中的组件进行交互,在开发Android应用时必须遵守单线程模型的原则:

    1. Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。

    2.不要阻塞UI线程。

    为什么说Android UI不是线程安全的?

    android UI 中提供invalidate()来更新界面,而invalidate()方法是线程不安全。

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在非UI主线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。例如:在非UI线程中调用invalidate会导致线程不安全,也就是说可能在非UI线程中刷新界面的时候,UI线程(或者其他非UI线程)也在刷新界面,这样就导致多个界面刷新的操作不能同步,导致线程不安全

    展开全文
  • 介绍StackTraceElement[]中保存了一条线程中所有调用的方法。其中每个方法的信息包含在一个StackTraceElement对象中。获取StackTraceElement中的信息element.getClassName(); //获取类名element.getMethodLine(); //...
  • } 用Activity对象的runOnUiThread方法更新,在子线程中通过runOnUiThread()方法更新UI,强烈推荐使用。 3. View.post(Runnable r) : private void three(){ new Thread(){ @Override public void run() { super....
  • 基于Android 6.0源码剖析,分析Android线程的创建过程/android/libcore/libart/src/main/java/java/lang/Thread.java/art/runtime/native/java_lang_Thread.cc/art/runtime/native/java_lang_Object.cc/art/runtime/...
  • 它是Java的特性,而不是Android特有的。一条“管道”为两个线程建立一个单向的通道。生产者负责写数据,消费者负责读取数据。下面是一个使用管道流进行通信的例子。public class PipeExampleActivity extends ...
  • Android 线程之自定义带消息循环Looper的实例Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也提供了封装有消息循环(Looper)的HandlerThread类,这种线程,可以绑定Handler()对象,并通过...
  • android 线程超时的例子import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.content.Intent;import ...
  • android线程状态

    2021-06-06 02:50:09
    一、线程同步:当两个或两个以上的线程同时访问一个资源。为了保护资源数据的安全,要求在同一时间只能一个线程访问该资源。同步造成的结果:1、数据安全 2、效率低下。二、线程死锁:当两个线程循环依赖于一对同步...
  • 背景介绍我们在Android开发过程中,几乎都离不开线程。但是你对线程的了解有多少呢?它***运行的背后,究竟隐藏了多少不为人知的秘密呢?线程间互通暗语,传递信息究竟是如何做到的呢?Looper、Handler、MessageQueue...
  • Android线程处理简述

    2021-06-08 01:02:56
    Android线程处理简述附件工程是有关Android线程的,里面对的&错的方式都有。遇到报错那就对了,先熟悉了,以后才更清楚不是吗^^。还有,运行结果就不都截图了,懒人一个T^T。一、基础篇1)UI线程概念Android为单...
  • android线程消息传递机制—Looper,Handler,Message一、机制的背景1.出于性能优化的考虑2.如果有多个线程同时操作某个UI组件,可能导致线程安全问题3.线程下载,完毕后怎么通知主线程二、线程安全1、类成为线程安全...
  • Android线程

    2021-06-08 08:33:41
    Android中实现多线程,常见的方法有:继承Thread类实现Runnable接口ThreadPoolExecutorAsyncTaskHandlerThreadLocalHandlerThreadIntentServiceThread具体使用// 步骤1:创建线程类 (继承自Thread类)class MyThread ...
  • 我不确定我现在是否真的需要这个功能,但如果我的应用程序扩展,我可以看到这种可能性。...我想让它线程安全,但我想用信号量来尝试它。我的SharedPreferences包装将从getSyncedPrefManager()中获得对以下类的...
  • 扩展知识线程和进程有什么区别?一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行...
  • 研究了 线程超时方面的东西基本思路触发事件之后 同时开启2个线程1-timer线程2-执行数据访问的thread线程3-Runnable线程线程用来更新UItimer线程设置CHECK_TIME秒之后执行,也就是访问的最大时间 超过此时间就视...
  • Android进程间和线程间通信方式

    千次阅读 2021-01-17 13:22:41
    线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。区别:(1)、一个程序至少有一个进程,一个进...
  • Android中子线程和UI线程之间通信的详细解释1.在多线程编程这块,我们经常要使用Handler,Thread和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢?下面详解一下。2.首先在开发Android应用时必须遵守单线程...
  • 当我们启动一个App的时刻,Android体系会启动一个Linux Process,该Process包含一个Thread,称为UI Thread或Main Thread。平日一个应用的所有组件都运行在章一?Process中,当然,你可以经由过程修改四大年夜组件在...
  • [android]代码库public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mTextView = (TextView) findViewById(R.id.myTextView);mHandler = new ...
  • Android线程介绍

    2021-05-27 08:05:10
    进程与线程进程:是操作系统的基础;是一次程序的执行;是一个程序及数据在处理机上顺序执行时所发生的活动;是程序在一个数据集合运动的过程;它是系统进行资源分配的一个独立单位。线程线程可以理解成是在进程中...
  • 1,通过Handler机制 ... } } 到此这篇关于android实现线程间通信的四种常见方式的文章就介绍到这了,更多相关android 线程间通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
  • 这篇文章主要介绍了Android线程中设置控件的值提示报错的解决方法,实例分析了textview报错的原因以及Handler设置来解决错误的实现技巧,需要的朋友可以参考下本文实例讲述了Android线程中设置控件的值提示报错的解决...
  • Android Profiler 的 CPU 中的THREADS 也能看到运行的线程只了解到这些...1.查看应用 进程 和 进程 对应的线程信息//查看应用包名所在的进程信息> adb shell ps -t | grep 包名USER PID PPID VSIZE RSS WCHAN PC ...
  • 四、单例模式注意事项 1、内存泄漏 单例模式在 Android 开发中会经常用到,但是如果使用不当就会导致内存泄露。因为单例的静态特性使得它的生命周期同应用的生命周期一样长,如果一个对象已经没有用处了,但是单例...
  • android中如果要在线程中实现页面跳转,其动画效果overridePendingTransition会失效。而我们有时候(比如启动页面)又必须用到,所以参考网上方法,利用Thread结合Handler方式最终得到解决,代码如下:参考网页:1....
  • android线程

    2021-06-07 03:23:53
    其实单线程模型就是默认情况下Android把所有操作都放在主线程也就是UI Thread线程中来执行 如果你想 O上边那段不是说它会阻塞用户界面嘛 那我可以另起一个线程来执行一些操作 没错你的想法非常good 。很给力。那么接...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 339,262
精华内容 135,704
关键字:

安卓的线程

友情链接: 工程光学-郁道银.zip