如何判断一个按键精灵判断线程是否启动已经启动

Android中检测当前是否为主线程最可靠的解决方法
投稿:junjie
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Android中检测当前是否为主线程最可靠的解决方法,本文先是给出了最可靠的方法,然后给出了几个实验例子,需要的朋友可以参考下
如果在Android中判断某个线程是否是主线程?对于这个问题,你可能说根据线程的名字,当然这个可以解决问题,但是这样是最可靠的么?万一某天Google一下子将线程的名字改称其他神马东西呢。
下面的方法是最可靠的解决方案。
public static boolean isInMainThread() {
&&&&& return Looper.myLooper() == Looper.getMainLooper();
实际上,写到这里就基本解决了文章标题的问题了,但是仅仅研究到这里太肤浅了,刨的不够深,所以需要继续,希望你也可以继续读下去。
好,现在,我们对这个稳定的方法做一些测试,首先,下面的方法会增加一些调试打印信息。
private boolean isInMainThread() {
&&& Looper myLooper = Looper.myLooper();
& Looper mainLooper = Looper.getMainLooper();
& Log.i(LOGTAG, "isInMainThread myLooper=" + myLooper
&&&&& + ";mainLooper=" + mainLooper);
& return myLooper == mainL
好,然后我们在主线程中运行一个测试,调用上述方法。比如我们这样调用。
Log.i(LOGTAG, "testInMainThread inMainThread=" + isInMainThread());
OK,我们看一下输出日志。验证OK。
I/TestInMainThread(32028): isInMainThread myLooper=Looper{40d35ef8};mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testInMainThread inMainThread=true
现在我们继续在一个没有消息循环的非主线程,进行验证。
new Thread() {
&&& @Override
&&& public void run() {
&&&&& Log.i(LOGTAG, "testIn NOT in MainThread isMainThread="
&&&&&&&&& + isInMainThread());
&&&&& super.run();
}.start();
正如我们看到的如下日志结果,主线程的Looper(翻译成循环泵,不是很好听)已经被初始化赋值。但是我们新创建的线程的looper还是null。这是因为Android中的线程默认没有一个和它绑定了的消息循环(Threads by default do not have a message loop associated with them. Of course, the method works)
I/TestInMainThread(32028): isInMainThread myLooper=mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testIn NOT in MainThread isMainThread=false
继续,我们创建一个绑定了消息循环的线程,根据Android开发者文档说明,以下是一个典型的创建消息循环线程的示例,使用单独prepare()方法和loop()方法来创建一个绑定到Looper的Handler。
new Thread() {
& private Handler mH
& @Override
& public void run() {
&&&&& Looper.prepare();
&&&&& mHandler = new Handler() {
&&&&&&&&&&& public void handleMessage(Message msg) {
&&&&&&&&&&&&& // process incoming messages here
&&&&&&&&& }
&&&&& Log.i(LOGTAG, "testInNonMainLooperThread isMainThread="
&&&&&&&&&&& + isInMainThread());
&&&&& Looper.loop();
}.start();
OK,现在再次检查以下日志,
I/TestInMainThread(32028): isInMainThread myLooper=Looper{40d72c58};mainLooper=Looper{40d35ef8}
I/TestInMainThread(32028): testInNonMainLooperThread isMainThread=false
两个Looper都被初始化赋值了,但是他们是不同的对象。
但是,这是为什么呢,这里面有什么奥秘呢? 好,让我们看以下Looper.class
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal&Looper& sThreadLocal = new ThreadLocal&Looper&();
private static Looper sMainL& // guarded by Looper.class
&* Initialize the current thread as a looper, marking it as an
&* application's main looper. The main looper for your application
&* is created by the Android environment, so you should never need
&* to call this function yourself.& See also: {@link #prepare()}
public static void prepareMainLooper() {
&&& prepare(false);
&&& synchronized (Looper.class) {
&&&&&&& if (sMainLooper != null) {
&&&&&&&&&&& throw new IllegalStateException("The main Looper has already been prepared.");
&&&&&&& sMainLooper = myLooper();
private static void prepare(boolean quitAllowed) {
&&& if (sThreadLocal.get() != null) {
&&&&&&& throw new RuntimeException("Only one Looper may be created per thread");
&&& sThreadLocal.set(new Looper(quitAllowed));
&* Return the Looper object associated with the current thread.&
&* Returns null if the calling thread is not associated with a Looper.
public static Looper myLooper() {
&&& return sThreadLocal.get();
&/** Returns the application's main looper, which lives in the main thread of the application.
public static Looper getMainLooper() {
&&& synchronized (Looper.class) {
&&&&&&& return sMainL
对于主线程来说,prepareMainLooper这个方法会被Android运行环境调用,而不是程序显式调用。通过这个方法,主线程的looper被创建,并且将对象引用传递给sMainLooper。所以保证了主线程myLooper()获取到的引用和getMainLooper()获取到的都是同一个引用。
对于没有消息循环的非主线程,默认的当前线程的looper是null,因为你从来没有手动地调用prepare(),所以它和主线程的looper不一样。
对于绑定了消息循环的非主线程,当调用Looper.prepare方法时,主线程的Looper已经由Android运行环境创建,当调用prepare方法后,绑定到这个非主线程的looper被创建,当然,这不可能和主线程的Looper一样。
综上所述,这个方法是可靠的。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具如何判断多个线程是否结束 - ITeye问答
我有个程序设计不明白了,
main里有有3部分代码,
第一部分开出15个线程,
第二部分需要第一部分的结果进行分析,
但是我无法判断第一步开出的15个线程是否结束,我只能手工屏蔽第二和第三部分代码,然后依次执行。
高手有什么办法没,如何判断15个线程是否结束。
就是如何让主线程等待所有子线程执行完毕
public class Test {
* @param args
public static void main(String[] args) {
// TODO Auto-generated method stub
// 第一部分从正式数据库抽取数据,插入临时表
for (int i = 0; i & 15; i++) {
new Thread() {
public void run() {
// TODO Auto-generated method stub
System.out.println("在正式数据库抽取数据:"
+ Thread.currentThread().getName());
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}.start();
// 第二部分,对临时表数据进行整理
System.out.println("插入临时表进行分析");
// 结果展示
System.out.println("从临时表中读取信息,结果展示");
问题补充我看一下,我原来考虑过线程组,但是也没有什么好的方法
你说的java.lang.Thread.State == TERMINATED 就可以
可以实现吗,这句应该写在哪里,第一部分代码的后面吗?
高手再指点下呀问题补充1: Thread.join()
2: CountDownLatch
3: CyclicBarrier
这三个都可以解决我说的那个问题吗,我是想第一部分15个线程都执行完后,再执行第二部分程序问题补充join(),是目标线程.join,是让目标线程加入,当前线程等目标线程执行完,再执行,这个可顶不符合我的要求。问题补充CountDownLatch 正解,看API描述,就是这个东西,太感谢了,这个问题困扰我很久。问题补充感谢各位高手的帮忙,我有思路了,谢谢了
采纳的答案
Part 1:
Thread[] ts = new Thread[15];
for(int i=0;i&ts.length();i++){
ts[i] = new Thread(){...}
ts[i].start();
}
for(int i=0;i&ts.length();i++){
ts[i].join();
}
...
Part2 : ....
albb0608 写道join(),是目标线程.join,是让目标线程加入,当前线程等目标线程执行完,再执行,这个可顶不符合我的要求。
楼主使用ExecutorCompletionService,具体怎么弄,我不告诉你!呵呵!
线程池都能做的!
请看我的文章:并发编程一波流之CyclicBarrier.
有实际代码,肯定能解决你的问题。
将创建好的线程加入数组或者List,然后遍历List,启动线程
然后遍历线程数组,调用join()等待线程执行结束,接下来的事情就可以继续做了。
1: Thread.join()2: CountDownLatch3: CyclicBarrier
通过Thread#getState() 来判断!java.lang.Thread.State == TERMINATED 就可以!也可以通过Profile工具查看的!
已解决问题
未解决问题C#定时检测子线程是否已经完成
C#定时检测子线程是否已经完成
class Program
static void Main(string[] args)
//主线程中启动一个支线程,执行doSomething这样的一个方法。
Thread thread = new Thread(new ThreadStart(ThreadRun));
thread.IsBackground =//这样能随主程序一起结束
thread.Start();
Console.ReadKey();
delegate void Delegate_do();
static void ThreadRun()
Delegate_do Delegate_do = new Delegate_do(FindAllProduct);
IAsyncResult result = Delegate_do.BeginInvoke(null, null);
while (!result.IsCompleted)
Console.WriteLine(&子线程未完成&);
Thread.Sleep(1000);//每隔1秒判断一下是否完成
while (true)
if (result.IsCompleted)
Console.WriteLine(&-------子线程已完成-------&);
catch (Exception ex)
Console.WriteLine(ex.Message);
static void FindAllProduct()
List array = new List();
for (int i = 0; i & ; i++)
array.Add(i);
int m = 0;
foreach (var i in array)
Console.WriteLine(m);
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'求大神指点。我这个是不是线程启动失败了?需要怎么判断线程是否成功开启? _ 综合讨论 - 按键精灵论坛
腾讯微博:
软件版本:2014.03软件大小:71.2M更新时间:10-25
软件版本:3.1.7软件大小:52.1M更新时间:12-12
软件版本:1.2.4软件大小:29.2M更新时间:10-28
软件版本:1.1.0软件大小:12.3M更新时间:12-29
查看: 1190|回复: 10
jeepjeep01
黄瓜勋章(永久)体验商业小精灵活动的奖励按键精灵开发者2级可通过提升认证等级来升级勋章:
本帖最后由 jeepjeep01 于
13:48 编辑 线程ID1=BeginThread(主程序)线程ID2=BeginThread(副程序一)线程ID3=BeginThread(副程序二)Do'输出 线程IDCall Plugin.Msg.ShowScrTXT(0, 0, ,线程ID1&线程ID2&线程ID3, "0000FF")
Delay 10000LoopSub 主程序TracePrint "主程序"TracePrint "找图找字找色"时间=nowIf 时间 >= 5 Then '因为如果时间大于5个小时不用RestartScript的话内存直接占满RestartScriptEnd IfEnd SubSub 副程序一TracePrint "创建大漠"Do'输出nowCall Plugin.Msg.ShowScrTXT(0,500, , "线程2正常运行"&now, "0000FF")
TracePrint "找图找字找色"I=Plugin.Web.Bind("程序.exe")A= Plugin.Window.Find(0, "程序")If I >= 1 Then ElseRestartScriptEnd IfIf A >= 1 Then ElseRestartScriptEnd IfLoopEnd SubSub 副程序二TracePrint "创建大漠"DoTracePrint "找图,'LoopEnd Sub第一次运行线程ID输出显示正常, 线程2正常运行now显示输出也正常中途运行了RestartScript后 线程ID输出显示正常|或者|线程2正常运行now显示输出也正常
就不显示了当主线程运行过程中程序.exe消失了 这时候副程序一里面的I=Plugin.Web.Bind("程序.exe")A = Plugin.Window.Find(0, "程序")的返回值肯定是=0的但是确没有执行RestartScript 因为前面"线程2正常运行"&now显示失败了的,所以感觉是线程启动失败了是吧?有什么办法检查线程启动失败的话就在启动?求大神指点(8.99 K) 13:46:20上面这张图是手动启动脚本运行后的显示 如果程序消失的话会运行
RestartScript 下面这张图是运行RestartScript 的显示,(6.61 K) 13:46:29这样显示的时候如果程序消失了(副线程一)不会做出判断 也不会运行
RestartScript
按键精灵开发者6级可通过提升认证等级来升级勋章:学有所成学有所成勋章,新手步入按键学堂的第一枚勋章鹰眼勋章鹰眼注册用户专属勋章黄瓜勋章(永久)体验商业小精灵活动的奖励幸运草勋章(永久)商业小精灵限时活动勋章。马年勋章(360天) 马年纪念勋章(360天)月全勤论坛自然月(如8.1-8.31)签到满勤,系统会在月底自动判断发放。
时间判断写的不对,应该写为:If DateDiff("h", 时间, now) >= 5 Then &&&&End IfNow的到的时间格式为: 12:48:44
这样的格式你怎么拿来跟5做大小判断???
jeepjeep01
黄瓜勋章(永久)体验商业小精灵活动的奖励按键精灵开发者2级可通过提升认证等级来升级勋章:
丑小七 发表于
12:50 时间判断写的不对,应该写为:If DateDiff("h", 时间, now) >= 5 Then &&&&时间判断是你那样写的。我现在的问题主要是副线程一感觉启动失败,进程消失了也不重新启动脚本,
黄瓜勋章(永久)体验商业小精灵活动的奖励
判断线程是否成功开启,在线程里面输出弹窗提示不就知道了,大不了在线程末尾加上个提示窗口这还不能用来测试是否成功运行了线程?有那么复杂?
黄瓜勋章(永久)体验商业小精灵活动的奖励
当然这只是测试线程是否成功执行。如果想在启动失败就自动启动线程,估计还要多加判断线程进行判断。这反而把问题复杂化。看你这代码,应该是找图的程序吧。有没有执行线程,这不能从找图的结果看出来?个人感觉没有必要再复杂化,把线程代码写法写得稳定点就够了,如果再多加线程判断,未必就更稳定。
黄瓜勋章(永久)体验商业小精灵活动的奖励
简单点说,想保障线程启动失败就自动启动失败的线程,肯定就得再加上线程对失败的线程进行监控。看看你的需要监控的线程成功执行的特征是什么,就以此为判断依据进行判断监控就可以了。否则就判断为线程没有成功执行,就自动再次启动失败的线程。
按键精灵开发者4级可通过提升认证等级来升级勋章:学有所成学有所成勋章,新手步入按键学堂的第一枚勋章黄金之翼黄金之翼勋章天使勋章天使一样的用户鹰眼勋章鹰眼注册用户专属勋章黄瓜勋章(永久)体验商业小精灵活动的奖励月全勤论坛自然月(如8.1-8.31)签到满勤,系统会在月底自动判断发放。年全勤论坛连续打卡签到365次以上(365天)马年勋章(360天) 马年纪念勋章(360天)
我就问一下,楼主这代码能挂着跑多久。电脑不错啊。。敢这么用
黄瓜勋章(永久)体验商业小精灵活动的奖励
dearhan 发表于
13:28我就问一下,楼主这代码能挂着跑多久。电脑不错啊。。敢这么用反正我是不会这样写代码,他的问题是这样子,所以就单纯就着他的问题回复一下咯。这样子的代码,估计稳定性不会很好。有的人的脚本,运行时间长了就开始各种不正常了,他的会怎样,看他运行具体情况了。
jeepjeep01
黄瓜勋章(永久)体验商业小精灵活动的奖励按键精灵开发者2级可通过提升认证等级来升级勋章:
hqnnqh24 发表于
13:17 判断线程是否成功开启,在线程里面输出弹窗提示不就知道了,大不了在线程末尾加上个提示窗口这还不能用来测 ...我在副线程一里面加了个Call Plugin.Msg.ShowScrTXT(0,500, , "线程2正常运行"&now, "0000FF")
但是用 RestartScript重新开始脚本后就不写频了 应该是启动失败了,。只有重新手动停止脚本在启动脚本才会写频,
jeepjeep01
黄瓜勋章(永久)体验商业小精灵活动的奖励按键精灵开发者2级可通过提升认证等级来升级勋章:
hqnnqh24 发表于
13:25 简单点说,想保障线程启动失败就自动启动失败的线程,肯定就得再加上线程对失败的线程进行监控。看看你的 ...我在Do'输出 线程IDCall Plugin.Msg.ShowScrTXT(0, 0, ,线程ID1&线程ID2&线程ID3, "0000FF")
Delay 10000Loop这里写频输出了所有线程的ID
这里写出来的id是有数字的呀,郁闷,
jeepjeep01
黄瓜勋章(永久)体验商业小精灵活动的奖励按键精灵开发者2级可通过提升认证等级来升级勋章:
dearhan 发表于
13:28 我就问一下,楼主这代码能挂着跑多久。电脑不错啊。。敢这么用3到4个小时运行一次 RestartScript
就正常使用 否者大于5个消失内存直接占满

我要回帖

更多关于 按键精灵判断线程是否启动 的文章

 

随机推荐