`
CshBBrain
  • 浏览: 654914 次
  • 性别: Icon_minigender_1
  • 来自: 成都
博客专栏
B7d9bf34-126e-301f-819e-81f2615b5a2a
开源WebSocket服务...
浏览量:145960
Group-logo
HTML5移动开发
浏览量:138803
社区版块
存档分类
最新评论

Activity中使用线程的例子

 
阅读更多

转自:http://blog.csdn.net/yihui823/article/details/6741411

 

今天看到一段很糟糕的代码。于是做了一个工程,模拟这段代码,向大家说明一下线程在使用中要注意的几点。这个例子适合给新手,也欢迎各位高手来指点一下。

首先,上代码。

第一个类LoginService,这是一个模拟类,把业务剥离出去了。只是模拟登录操作而已。

 

 

[java] view plaincopy
  1. package com.study;  
  2. package com.study;  
  3.   
  4. /** 
  5.  * 虚拟的一个登录服务. 
  6.  * @author yihui823 
  7.  */  
  8. public class LoginService {  
  9.   
  10.     //单例  
  11.     private static LoginService oneInstance = new LoginService();  
  12.       
  13.     /** 
  14.      * 得到唯一的一个单例 
  15.      * @return 唯一的一个单例 
  16.      */  
  17.     public static LoginService getInstance() {  
  18.         return oneInstance;  
  19.     }  
  20.       
  21.     //登录成功标记  
  22.     private boolean hadLogin = false;  
  23.       
  24.     /** 
  25.      * 模拟登录操作 
  26.      * @return true:登录成功 
  27.      */  
  28.     public boolean login() {  
  29.         try {  
  30.             Thread.sleep(2000);  
  31.         } catch (InterruptedException e) {  
  32.         }  
  33.         hadLogin = true;  
  34.         return hadLogin;  
  35.     }  
  36.       
  37.     /** 
  38.      * 判断是否登录 
  39.      * @return true:已经登录 
  40.      */  
  41.     public boolean isLogin() {  
  42.         return hadLogin;  
  43.     }  
  44. }  


第二个类就是我们的Activity了。

 

 

 

[java] view plaincopy
  1. package com.study;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.Toast;  
  6.   
  7. /** 
  8.  * 一个段不好的代码 
  9.  * @author yihui823 
  10.  */  
  11. public class BadCodeActivity extends Activity {  
  12.       
  13.     //登录服务  
  14.     private LoginService lService = LoginService.getInstance();  
  15.       
  16.     /** Called when the activity is first created. */  
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.   
  22.         new Thread(new Runnable() {  
  23.             @Override  
  24.             public void run() {  
  25.                 while(!lService.isLogin() ) {  
  26.                     try {  
  27.                         lService.login();  
  28.                         Thread.sleep(1000);  
  29.                     } catch (InterruptedException e) {  
  30.                         e.printStackTrace();  
  31.                     }  
  32.                 }  
  33.                 Toast.makeText(BadCodeActivity.this"登录成功", Toast.LENGTH_LONG).show();  
  34.             }  
  35.         }).start();  
  36.     }  
  37. }  

 

[java] view plaincopy
  1. <span style="background-color: rgb(255, 255, 255);">这个例子呢,显然运行的时候会报错的。请见我的另一篇文章:<a href="http://blog.csdn.net/yihui823/article/details/6722784" target="_blank">Android画面UI中的线程约束</a>。我们在非UI线程里去控制UI界面,就必须使用Handler来发送消息。修改代码如下:</span>  

 

 

 

[java] view plaincopy
  1. package com.study;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.widget.Toast;  
  8.   
  9. /** 
  10.  * 一个段不好的代码 
  11.  * @author yihui823 
  12.  */  
  13. public class BadCodeActivity extends Activity {  
  14.       
  15.     //登录服务  
  16.     private LoginService lService = LoginService.getInstance();  
  17.       
  18.     <span style="color:#ff6666;">//外线程访问UI线程的Handle  
  19.     private Handler mhandle = new Handler(){  
  20.         @Override  
  21.         public void handleMessage(Message msg) {  
  22.             Toast.makeText(BadCodeActivity.this"登录成功", Toast.LENGTH_LONG).show();  
  23.         }  
  24.     };</span>  
  25.       
  26.       
  27.     /** Called when the activity is first created. */  
  28.     @Override  
  29.     public void onCreate(Bundle savedInstanceState) {  
  30.         super.onCreate(savedInstanceState);  
  31.         setContentView(R.layout.main);  
  32.   
  33.         new Thread(new Runnable() {  
  34.             @Override  
  35.             public void run() {  
  36.                 while(!lService.isLogin() ) {  
  37.                     try {  
  38.                         lService.login();  
  39.                         Thread.sleep(1000);  
  40.                     } catch (InterruptedException e) {  
  41.                         e.printStackTrace();  
  42.                     }  
  43.                 }  
  44.                 <span style="color:#ff0000;">mhandle.sendEmptyMessage(0);</span>  
  45.             }  
  46.         }).start();  
  47.     }  
  48. }  

 

[java] view plaincopy
  1. <p><span style="background-color: rgb(255, 255, 255);">红色部分代码,就是修改的地方。现在,这段代码可以运行了,而且还貌似不错,是吧。</span></p><p><span style="background-color: rgb(255, 255, 255);">但是,一个好的程序,不能只是应付正常情况,还要应付错误情况,是吧。如果登录总是出错怎么样呢?我们把LoginService类略微改动,如下:</span></p>  

 

 

 

[java] view plaincopy
  1. package com.study;  
  2.   
  3. import android.util.Log;  
  4.   
  5. /** 
  6.  * 虚拟的一个登录服务. 
  7.  * @author yihui823 
  8.  */  
  9. public class LoginService {  
  10.   
  11.     private static final String TAG = "LoginService";  
  12.       
  13.     //单例  
  14.     private static LoginService oneInstance = new LoginService();  
  15.       
  16.     /** 
  17.      * 得到唯一的一个单例 
  18.      * @return 唯一的一个单例 
  19.      */  
  20.     public static LoginService getInstance() {  
  21.         return oneInstance;  
  22.     }  
  23.       
  24.     //登录成功标记  
  25.     private boolean hadLogin = false;  
  26.       
  27.     /** 
  28.      * 模拟登录操作 
  29.      * @return true:登录成功 
  30.      */  
  31.     public boolean login() {  
  32.         try {  
  33.             Thread.sleep(2000);  
  34.         } catch (InterruptedException e) {  
  35.         }  
  36.         Log.d(TAG, "we are login");  
  37. //      hadLogin = true;  
  38.           
  39.         return hadLogin;  
  40.     }  
  41.       
  42.     /** 
  43.      * 判断是否登录 
  44.      * @return true:已经登录 
  45.      */  
  46.     public boolean isLogin() {  
  47.         return hadLogin;  
  48.     }  
  49. }  


增加了Log,以便查看登录情况。模拟业务代码只改了一行,就是登录永远是失败。现在运行一下呢。停在页面上没有动静了,logcat里也不断的打出:
we are login
这个也不会有什么错误,对吧。但是,我们如果按“返回”键退出页面,再看看logcat呢?
we are login的log还在不停的输出,是吗?
我想现在大家应该知道哪里出了问题了。就是说,我们的线程启动之后,就没法停掉了。
这里我要说一下。我一直认为,
new Thread(new Runnable() {…}().start();
这种代码写的非常的不好。你直接构造了一个对象,但是这个对象你没有任何的变量去指向它。这个线程被你启动之后,你已经无法再去跟踪、调用、管理了。这个线程,只能自生自灭,永远游离在你的控制范围之外。你会不会觉得,这个线程跟僵尸一样?对,这就是僵尸进程,如果它没有停止的条件,就永远在你的系统里消耗你的资源。
所以我觉得使用线程的一个基本认识:生成的线程类,一定要有一个变量去指向它,以便在合适的时候销毁。
这里说到销毁,这就是另一个问题了。Thread类已经废弃了stop方法了,因为线程需要自行去释放该释放的资源,不能光依赖于运行框架的控制。我们需要在Thread里面,加上他自己停止的代码。也就是说,不论如何,线程应该会自己去停止掉,而不应该是无限制的运行。
另外,我们在Android里面,还应该注意Activity的各个状态周转。一般来说,线程的启动在onCreate里是不合适的,我们必须考虑到onResume和onPause的情况。
那么,我们总结下,Activity里使用线程有三个注意:
1, 线程对象一定要有变量指向它,以便我们可以控制。
2, 线程类一定要有停止条件,以便外界通知线程自行停止。
3, 在onResume里启动线程,在onPause里停止线程

我们根据以上三点,重新写一下Activity。

 

 

 

[java] view plaincopy
  1. package com.study;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.util.Log;  
  8. import android.widget.Toast;  
  9.   
  10. /** 
  11.  * 一个段不好的代码 
  12.  * @author yihui823 
  13.  */  
  14. public class BadCodeActivity extends Activity {  
  15.   
  16.     private static final String TAG = "BadCodeActivity";  
  17.       
  18.     //登录服务  
  19.     private LoginService lService = LoginService.getInstance();  
  20.       
  21.     //外线程访问UI线程的Handle  
  22.     private Handler mhandle = new Handler(){  
  23.         @Override  
  24.         public void handleMessage(Message msg) {  
  25.             Toast.makeText(BadCodeActivity.this"登录成功", Toast.LENGTH_LONG).show();  
  26.         }  
  27.     };  
  28.       
  29.     //通知停止线程的标记  
  30.     private boolean stopFlag = false;  
  31.       
  32.     //登录成功标记  
  33.     private boolean loginOk = false;  
  34.       
  35.     /** 
  36.      * 登录用的线程类 
  37.      */  
  38.     private class LoginThread extends Thread {  
  39.           
  40.         @Override  
  41.         public void run() {  
  42.             while(!stopFlag) {  
  43.                 loginOk = lService.isLogin();  
  44.                 if (loginOk) {  
  45.                     break;  
  46.                 }  
  47.                 try {  
  48.                     lService.login();  
  49.                     Thread.sleep(1000);  
  50.                 } catch (InterruptedException e) {  
  51.                     e.printStackTrace();  
  52.                 }  
  53.             }  
  54.             mhandle.sendEmptyMessage(0);  
  55.         }  
  56.           
  57.         /** 
  58.          * 通知线程需要停止 
  59.          */  
  60.         public void stopLogin() {  
  61.             stopFlag = true;  
  62.         }  
  63.     };  
  64.   
  65.     //用来登录的线程  
  66.     private LoginThread loginThread = new LoginThread();  
  67.       
  68.       
  69.     /** Called when the activity is first created. */  
  70.     @Override  
  71.     public void onCreate(Bundle savedInstanceState) {  
  72.         super.onCreate(savedInstanceState);  
  73.         setContentView(R.layout.main);  
  74.         Log.d(TAG, "BadCodeActivity instance is called onCreate :" + this.hashCode());  
  75.     }  
  76.       
  77.     public void onResume() {  
  78.         super.onResume();  
  79.         Log.d(TAG, "BadCodeActivity instance is called onResume :" + this.hashCode());  
  80.         loginThread.start();  
  81.     }  
  82.       
  83.     public void onPause() {  
  84.         super.onPause();  
  85.         loginThread.stopLogin();  
  86.     }  
  87. }  


现在,我们的线程可以在页面退出的时候正常停止了。
 
但是这段代码还是有问题的。我们仔细看看,线程在Activity构造的时候就已经创建了,然后在程序进到前台的时候启动,退到后台的时候停止。但是线程有这么一个特性:
一旦线程的run()函数运行结束了,这个线程就销毁了,不能再启动了。
现在我们的程序,在退出后将不可能再次显示,所以系统会马上回收掉Activity。如果我们的页面增加一个按钮,迁移到另一个页面,那么在那个页面返回的时候,就会有异常出现。我们修改一下代码来试试。
增加一个Activity:

 

 

[java] view plaincopy
  1. package com.study;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5.   
  6. /** 
  7.  * 临时页面 
  8.  * @author yihui823 
  9.  */  
  10. public class TempActivity extends Activity {  
  11.   
  12.     /** Called when the activity is first created. */  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.main);  
  17.     }  
  18. }  



 

[java] view plaincopy
  1. <pre class="java" name="code"></pre>  
  2. <p>别忘了修改AndroidManifest.xml,增加Activity的说明:</p>  
  3. <p align="left">         <activity android:name=".TempActivity"<br>  
  4.                   android:label="@string/app_name"/><br>  
  5. </p>  
  6. <p align="left">修改BadCodeActivity:</p>  
  7. <p><br>  
  8. </p>  
  9. <pre class="java" name="code">package com.study;  
  10.   
  11. import android.app.Activity;  
  12. import android.content.Intent;  
  13. import android.os.Bundle;  
  14. import android.os.Handler;  
  15. import android.os.Message;  
  16. import android.util.Log;  
  17. import android.view.View;  
  18. import android.view.View.OnClickListener;  
  19. import android.widget.Button;  
  20. import android.widget.Toast;  
  21.   
  22. /** 
  23.  * 一个段不好的代码 
  24.  * @author yihui823 
  25.  */  
  26. public class BadCodeActivity extends Activity {  
  27.   
  28.     private static final String TAG = "BadCodeActivity";  
  29.       
  30.     //登录服务  
  31.     private LoginService lService = LoginService.getInstance();  
  32.       
  33.     //外线程访问UI线程的Handle  
  34.     private Handler mhandle = new Handler(){  
  35.         @Override  
  36.         public void handleMessage(Message msg) {  
  37.             Toast.makeText(BadCodeActivity.this"登录成功", Toast.LENGTH_LONG).show();  
  38.         }  
  39.     };  
  40.       
  41.     //通知停止线程的标记  
  42.     private boolean stopFlag = false;  
  43.       
  44.     //登录成功标记  
  45.     private boolean loginOk = false;  
  46.       
  47.     /** 
  48.      * 登录用的线程类 
  49.      */  
  50.     private class LoginThread extends Thread {  
  51.           
  52.         @Override  
  53.         public void run() {  
  54.             while(!stopFlag) {  
  55.                 loginOk = lService.isLogin();  
  56.                 if (loginOk) {  
  57.                     break;  
  58.                 }  
  59.                 try {  
  60.                     lService.login();  
  61.                     Thread.sleep(1000);  
  62.                 } catch (InterruptedException e) {  
  63.                     e.printStackTrace();  
  64.                 }  
  65.             }  
  66.             mhandle.sendEmptyMessage(0);  
  67.         }  
  68.           
  69.         /** 
  70.          * 通知线程需要停止 
  71.          */  
  72.         public void stopLogin() {  
  73.             stopFlag = true;  
  74.         }  
  75.     };  
  76.   
  77.     //用来登录的线程  
  78.     private LoginThread loginThread = new LoginThread();  
  79.       
  80.       
  81.     /** Called when the activity is first created. */  
  82.     @Override  
  83.     public void onCreate(Bundle savedInstanceState) {  
  84.         super.onCreate(savedInstanceState);  
  85.         setContentView(R.layout.main);  
  86.           
  87.  <span style="color:#ff0000;">       Button btn = (Button)findViewById(R.id.btn);  
  88.         btn.setOnClickListener(new OnClickListener() {  
  89.             @Override  
  90.             public void onClick(View arg0) {  
  91.                 startActivity(new Intent(BadCodeActivity.this,TempActivity.class));  
  92.             }  
  93.         });</span>  
  94.           
  95.         Log.d(TAG, "BadCodeActivity instance is called onCreate :" + this.hashCode());  
  96.     }  
  97.       
  98.     public void onResume() {  
  99.         super.onResume();  
  100.         Log.d(TAG, "BadCodeActivity instance is called onResume :" + this.hashCode());  
  101.         loginThread.start();  
  102.     }  
  103.       
  104.     public void onPause() {  
  105.         super.onPause();  
  106.         loginThread.stopLogin();  
  107.     }  
  108. }  
  109. </pre>  
  110. <p><br>  
  111. </p>  
  112. <p align="left"> </p>  
  113. <p>其实就是加了一个按钮,做一个页面迁移。别忘了在main.xml里面加上:</p>  
  114. <pre class="html" name="code"><Button  
  115.     android:id="@+id/btn"    
  116.     android:layout_width="fill_parent"   
  117.     android:layout_height="wrap_content"   
  118.     android:text="@string/hello"  
  119.     />  
  120. </pre>  
  121. <p><br>  
  122.  </p>  
  123. <p>现在我们运行程序。运行之后,点击按钮,画面闪动一下说明是切换了页面。我们偷了个懒,两个Activity共用一个layout,所以页面没有任何变化。但是没关系,我们看log,we are login已经停止输出了。这个时候,我们再按返回键,应该是切换回BadCodeActivity。这个时候系统报错:</p>  
  124. <p>java.lang.IllegalThreadStateException: Thread already started.</p>  
  125. <p>显然,就是说线程已经启动过了,不能再次被利用。</p>  
  126. <p>我们对代码需要做一点点修改。当然,我们也顺手改掉一个BUG:在退出的时候还会报告登录成功。</p>  
  127. <p>并且,我们把控制变量都放在内部类里,做到变量最小化生存空间。</p>  
  128. <p>修改后如下:</p>  
  129. <pre class="java" name="code">package com.study;  
  130.   
  131. import android.app.Activity;  
  132. import android.content.Intent;  
  133. import android.os.Bundle;  
  134. import android.os.Handler;  
  135. import android.os.Message;  
  136. import android.util.Log;  
  137. import android.view.View;  
  138. import android.view.View.OnClickListener;  
  139. import android.widget.Button;  
  140. import android.widget.Toast;  
  141.   
  142. /** 
  143.  * 一个段不好的代码 
  144.  * @author yihui823 
  145.  */  
  146. public class BadCodeActivity extends Activity {  
  147.   
  148.     private static final String TAG = "BadCodeActivity";  
  149.       
  150.     //登录服务  
  151.     private LoginService lService = LoginService.getInstance();  
  152.       
  153.     //外线程访问UI线程的Handle  
  154.     private Handler mhandle = new Handler(){  
  155.         @Override  
  156.         public void handleMessage(Message msg) {  
  157.             Toast.makeText(BadCodeActivity.this"登录成功", Toast.LENGTH_LONG).show();  
  158.         }  
  159.     };  
  160.       
  161.     /** 
  162.      * 登录用的线程类 
  163.      */  
  164.     private class LoginThread extends Thread {  
  165.   
  166.         //通知停止线程的标记  
  167.         private boolean stopFlag = false;  
  168.           
  169.         //登录成功标记  
  170.         private boolean loginOk = false;  
  171.           
  172.         @Override  
  173.         public void run() {  
  174.             while(!stopFlag) {  
  175.                 loginOk = lService.isLogin();  
  176.                 if (loginOk) {  
  177.                     break;  
  178.                 }  
  179.                 try {  
  180.                     lService.login();  
  181.                     Thread.sleep(1000);  
  182.                 } catch (InterruptedException e) {  
  183.                     e.printStackTrace();  
  184.                 }  
  185.             }  
  186.             if (loginOk) {  
  187.                 mhandle.sendEmptyMessage(0);  
  188.             }  
  189.         }  
  190.           
  191.         /** 
  192.          * 通知线程需要停止 
  193.          */  
  194.         public void stopLogin() {  
  195.             stopFlag = true;  
  196.         }  
  197.     };  
  198.   
  199.     //用来登录的线程  
  200.     private LoginThread loginThread;  
  201.       
  202.       
  203.     /** Called when the activity is first created. */  
  204.     @Override  
  205.     public void onCreate(Bundle savedInstanceState) {  
  206.         super.onCreate(savedInstanceState);  
  207.         setContentView(R.layout.main);  
  208.           
  209.         Button btn = (Button)findViewById(R.id.btn);  
  210.         btn.setOnClickListener(new OnClickListener() {  
  211.             @Override  
  212.             public void onClick(View arg0) {  
  213.                 startActivity(new Intent(BadCodeActivity.this,TempActivity.class));  
  214.             }  
  215.         });  
  216.           
  217.         Log.d(TAG, "BadCodeActivity instance is called onCreate :" + this.hashCode());  
  218.     }  
  219.       
  220.     public void onResume() {  
  221.         super.onResume();  
  222.         Log.d(TAG, "BadCodeActivity instance is called onResume :" + this.hashCode());  
  223.         <span style="color:#ff0000;">loginThread = new LoginThread();</span>  
  224.         loginThread.start();  
  225.     }  
  226.       
  227.     public void onPause() {  
  228.         super.onPause();  
  229.         loginThread.stopLogin();  
  230.     }  
  231. }  
  232.   
  233. </pre>  
  234. <p align="left"><br>  
  235.  </p>  
  236. <p>现在,我们点击按钮,进入到TempActivity的时候,登录log停止输出;然后按返回键,回到BadCodeActivity的时候,登录log又继续输出。程序基本完成,没有僵尸线程存在了。红色的那行代码是关键!</p>  
  237. <p>我们总结一下:</p>  
  238. <p><strong>1, 线程对象一定要有变量指向它,以便我们可以控制。</strong></p>  
  239. <p><strong>2, 线程类一定要有停止条件,以便外界通知线程自行停止。</strong></p>  
  240. <p><strong>3, 线程启动之后,不管是不是已经停止了,都是不能再次利用的。</strong></p>  
  241. <p>4,  <strong>在onResume里新建和启动线程,在onPause里停止线程。</strong></p>  
  242. <p> </p>  
  243. <p> </p>  
  244. <pre></pre>  
  245. <pre></pre>  
  246. <pre></pre>  
  247. <pre></pre>  
分享到:
评论

相关推荐

    android两个activity的例子

    如果你需要在两个Activity之间传递数据,可以在创建`Intent`时使用`putExtra()`方法添加键值对,然后在接收方Activity中使用`getExtra()`来获取这些数据。 在`SecondActivity`中,通常会有一个返回到`FirstActivity...

    安卓通过线程刷新view的例子

    1. **runOnUiThread()**:这是一个Activity提供的方法,可以直接在非UI线程中调用,将指定的Runnable对象放入主线程的消息队列,等待主线程执行。 2. **View.post(Runnable)**:类似于`runOnUiThread()`,可以将一...

    splash 线程控制登录例子

    在这个例子中,"Splash Screen"是在应用启动时显示的一个短暂页面,通常用来展示品牌标识、加载资源或者进行初始化工作。为了实现Splash Screen,开发者通常会在后台线程加载数据或资源,同时在主线程更新进度条,让...

    Fragment与Activity之间通信实例

    在Android应用开发中,Fragment和Activity是两个核心组件,它们共同构建了用户界面。Fragment代表一个可重用的UI部分,而Activity则是程序中的一个窗口,它可以包含一个或多个Fragment。Fragment与Activity之间的...

    工作线程 UI线程实例

    在这个例子中,我们不需要Progress和Result,所以可以为空。 - 在`doInBackground(Params... params)`方法中,实现网络请求和图片下载。这个方法会在后台线程执行,不会阻塞UI。 - 使用`publishProgress()`方法...

    简单的handle demo 实现计时器功能,亲测可用,线程例子

    9. **源代码分析**:HandlerDemo可能包含一个主Activity,其中初始化了Handler,并在onCreate()或onResume()中启动计时器。同时,Runnable的run()方法可能包含对计时器行为的逻辑,比如每过一段时间更新UI或者执行...

    安卓线程间函数调用

    在这个例子中,`handleMessage()`方法会在UI线程中被执行,从而安全地更新了UI。 #### 总结 线程间的函数调用在Android开发中极为常见。使用`Handler`机制可以在非UI线程中执行耗时任务,并将结果安全地同步回UI...

    Android Service与Activity交互

    在这个例子中,我们可能会使用startService(),因为Service将独立于Activity运行,即使Activity被销毁,Service依然会继续执行。 Service内部,我们将开启一个新的线程,避免阻塞主线程。在新线程中,我们可以执行...

    android 线程间通信显示同步时间

    在"android 线程间通信显示同步时间"的例子中,我们可以选择使用Handler或LiveData。例如,创建一个后台线程,周期性获取系统时间,然后通过Handler发送一个包含新时间的Message到主线程。主线程的Handler接收到...

    Android主线程给多个线程发送消息

    在你的例子中,文件名为`MyHandler2`,可能包含了一个自定义的`Handler`实现,可能用于处理更复杂的逻辑,如并发控制、消息分发策略等。 总结来说,Android主线程通过`Handler`和`Looper`机制可以有效地与多个工作...

    利用 CountDownLatch 类实现线程同步

    在这个例子中,3个线程分别执行任务,每个任务完成后调用 `countDown()`。主线程调用 `await()` 阻塞,直到计数器归零,表明所有线程已完成任务,主线程继续执行后续操作。 总的来说,`CountDownLatch` 是一种有效...

    AsyncTask 异步多线程加载Demo

    在`AsyncTaskDemo`这个项目中,我们可能可以看到一个简单的例子,如何使用`AsyncTask`来加载数据,比如从网络下载文件或者数据库查询。开发者通常会模拟一个耗时操作,在`doInBackground()`中添加睡眠时间,然后在`...

    Android的线程使用来更新UI

    在这个例子中,`myThread`是一个在后台运行的线程,它不断地发送消息给`myHandler`,后者在主线程中接收到消息后更新UI。 ### Timer 和 TimerTask 除了`Thread`和`Handler`外,`Timer`和`TimerTask`也可以用来执行...

    Android经典代码例子

    例子可能包括了各种Activity状态的处理,如onCreate(), onStart(), onResume(), onPause(), onStop()和onDestroy()等方法的使用,以及如何在不同场景下正确管理它们。 2. **Intent的使用**:Intent用于启动或激活...

    线程回调demo

    它可能演示了如何创建一个工作线程,定义回调接口,并在主线程中使用这个接口来接收和处理来自工作线程的结果。为了运行这个例子,你需要确保正确导入所有必要的库,创建并启动线程,并传递实现了回调接口的对象。 ...

    测试Service中开启Thread

    在Android应用开发中,`Service` 是一个用于执行长时间运行操作的组件,它不提供用户界面,但可以与用户界面组件交互。...通过分析和学习这个示例,开发者可以更好地理解和实践在`Service` 中使用线程的技术。

    Activity的生命周期

    - **示例**:假设Activity中包含一个用于从网络下载数据的后台线程,那么可以在`onCreate()`中启动这个线程,在`onDestroy()`中确保线程被正确停止。 2. **可见生命周期**:从`onStart()`到`onStop()`。这一阶段...

    Android Application Development_O’Reilly中的例子

    你可以从例子中学习如何创建、启动和绑定Service,以及如何处理生命周期事件。 6. **AsyncTask**和**线程管理**:Android应用通常需要在后台线程执行耗时操作,避免阻塞UI。书中的例子可能会介绍AsyncTask的使用,...

    登录认证小例子

    在这个安卓小例子中,我们可能会看到如何处理用户输入、如何构建网络请求以及如何处理响应。 安卓线程的概念在此过程中至关重要。由于Android系统主要在主线程(UI线程)上运行,所有与用户界面交互的任务都必须在...

    Android开发之AsyncTask机制及使用细节例子源码

    在Android应用开发中,异步任务(AsyncTask)是一个常用工具,用于在后台线程执行耗时操作,然后在UI线程更新结果,避免阻塞用户界面。AsyncTask的使用和内部机制对于任何Android开发者来说都至关重要。让我们深入...

Global site tag (gtag.js) - Google Analytics