【Android】《第一行代码—Android》第九章总结
2016-01-13 00:18
375 查看
前面几章介绍了
服务—
Android多线程编程
Android多线程编程无论从语法上,还是从使用技巧上都与Java多线程编程类似,有三种方式开启子线程。下面会分别介绍。方式一很常规,直接自定义
这样我们就只需要创建线程实现类的对象,通过对象调用器start()方法,这样
鉴于方式一使用继承的方式,耦合性有点高。方式二主要使用实现
方式三的写法更为常见,使用匿名类的方式,如下
接下来我们来尝试“通过子线程进行UI操作”,如果你真的以为子线程可以直接操作UI,程序会直接崩溃掉。事实上也确实如此,Android确实是不允许在子线程中进行UI操作的。但我们可以借助Android异步消息处理机制,完美解决面临的问题。先看代码如下
上面分别给出了
首先Android的异步消息处理机制提供了一整套的消息处理流程,
Service基本用法
我们先要明确,服务的处理逻辑是独立于
主要介绍了服务的创建、启动、销毁,以及可以自动销毁的服务—
Service实践:后台执行定时服务
实践这部分我只贴出代码如下
Activity、
BroadcastReceiver、
ContentProvider等内容,本章对Android四大组件的最后一个组件
Service进行了较为全面的讲解,涉及到Android多线程、
Service的基本用法、
Service生命周期的介绍等等东西,内容比较多,但都很好理解,我也是在一天之内就把这一章的内容全部看完的,所以趁现在夜深人静的时候,把总结尽可能详细的写下来,说做就做现在动手!
服务—
Service—Android实现应用程序后台运行的解决方案,它非常适合去执行那些不需要和用户交互而且还要长期运行的任务。需要注意的是,服务并不是运行在一个独立的进程之中的,而是依赖于创建服务时所在的应用程序进程。换句话说,当某个应用程序的进程被杀掉时,所有依赖于该进程的服务也会停止运行。
Android多线程编程
Android多线程编程无论从语法上,还是从使用技巧上都与Java多线程编程类似,有三种方式开启子线程。下面会分别介绍。方式一很常规,直接自定义
Thread抽象类的实现类,重写父类的
run()方法并在方法体内添加耗时处理逻辑,如下
class MyThread extends Thread { @Override public void run() { //耗时处理逻辑 } }
这样我们就只需要创建线程实现类的对象,通过对象调用器start()方法,这样
run()方法体中的逻辑就会在子线程中运行了。如下
new MyThread().start();
鉴于方式一使用继承的方式,耦合性有点高。方式二主要使用实现
Runnable()接口的方式来定义一个线程。如下
class MyThread implements Runnable { @Override public void run() { //处理具体逻辑 } }
Thread构造函数接收一个
Runnable参数,我们正好可以传入
new MyThread()匿名对象作为参数,接着调用
start()方法启动线程,如下
new Thread(new MyThread()).start();
方式三的写法更为常见,使用匿名类的方式,如下
new Thread(new Runnable() { @Override public void run() { //具体处理逻辑 } }).start();
接下来我们来尝试“通过子线程进行UI操作”,如果你真的以为子线程可以直接操作UI,程序会直接崩溃掉。事实上也确实如此,Android确实是不允许在子线程中进行UI操作的。但我们可以借助Android异步消息处理机制,完美解决面临的问题。先看代码如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/change_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/change_text" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/hello_world" android:textSize="20sp" /> </RelativeLayout>
package com.example.androidthreadtest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private static final int UPDATE_TEXT = 1; private TextView text; private Button changeText; private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_TEXT: // 在这里可以进行UI操作 text.setText("nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (TextView) findViewById(R.id.text); changeText = (Button) findViewById(R.id.change_text); changeText.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.change_text: new Thread(new Runnable() { @Override public void run() { Message message = new Message(); message.what = UPDATE_TEXT; handler.sendMessage(message); // 将Message对象发送出去 } }).start(); break; default: break; } } }
上面分别给出了
activity_main.xml布局文件和
MainActivity.java文件的代码,我们可以通过点击按钮把
hello world变成
nice to meet you,那么处理的思路是什么呢?
首先Android的异步消息处理机制提供了一整套的消息处理流程,
Handler既可以发送消息,又包含消息的处理逻辑。我们可以利用
Handler对象调用其
sendMessage()方法在子线程中发送出一条消息,这条消息就包含更新UI的指令,注意!这条消息是在子线程中发送出去的。很快主线程
Handler对象就会接收到这条带有更新UI指令的消息,接着就会在主线程中完成对UI的更新操作。哈哈,到这里问题是不是解决很完美呢?其实上面的代码就是按照这个逻辑去写的。
Service基本用法
我们先要明确,服务的处理逻辑是独立于
Activity之外的,换句话说,服务并不需要依赖于Activity而存在,所以自然的,定义
Service的代码我们就用
MyService类去实现,
MyService类作为
Service的实现类,不仅要继承自
Service,还要实现
Service的抽象方法。下面我们来看代码如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/start_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/start_service" /> <Button android:id="@+id/stop_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/stop_service" /> <Button android:id="@+id/bind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/bind_service" /> <Button android:id="@+id/unbind_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/unbind_service" /> <Button android:id="@+id/start_intent_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/start_intentservice" /> </LinearLayout>
package com.example.servicetest; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private DownloadBinder mBinder = new DownloadBinder(); class DownloadBinder extends Binder { public void startDownload() { Log.d("MyService", "startDownload executed"); } public int getProgress() { Log.d("MyService", "getProgress executed"); return 0; } } @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public void onCreate() { super.onCreate(); /* * 下面的notification部分写法Android官方已经不推荐这样用 * 由于《第一行代码——Android》实在Android 4.0的基础上开发的 * 所以会这样。 * * */ Notification notification = new Notification(R.drawable.ic_launcher, "notification comes", System.currentTimeMillis()); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, "this is title", "this is content", pendingIntent); startForeground(1, notification); Log.d("MyService", "onCreate executed"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("MyService", "onStartCommand executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("MyService", "onDestroy executed"); } }
package com.example.servicetest; import android.app.IntentService; import android.content.Intent; import android.util.Log; public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); // 提供一个无参构造,在其内部调用其父类的有参构造函数 } @Override public void onDestroy() { super.onDestroy(); Log.d("MyIntnetService", "onDestroy executed"); } @Override protected void onHandleIntent(Intent intent) { // 打印当前线程的id Log.d("MyIntnetService", "thread id is " + Thread.currentThread().getId()); } }
package com.example.servicetest; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { private Button startService; private Button stopService; private Button bindService; private Button unbindService; private MyService.DownloadBinder downloadBinder; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { downloadBinder = (MyService.DownloadBinder) service; downloadBinder.startDownload(); downloadBinder.getProgress(); } @Override public void onServiceDisconnected(ComponentName name) { } }; private Button startIntentService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService = (Button) findViewById(R.id.start_service); stopService = (Button) findViewById(R.id.stop_service); startService.setOnClickListener(this); stopService.setOnClickListener(this); bindService = (Button) findViewById(R.id.bind_service); unbindService = (Button) findViewById(R.id.unbind_service); bindService.setOnClickListener(this); unbindService.setOnClickListener(this); startIntentService = (Button) findViewById(R.id.start_intent_service); startIntentService.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_service: Intent startIntent = new Intent(this, MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntent = new Intent(this, MyService.class); stopService(stopIntent); break; case R.id.bind_service: Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE); break; case R.id.unbind_service: unbindService(connection); // 解绑服务 break; case R.id.start_intent_service: // 打印主线程id Log.d("MainActivity", "thread id is " + Thread.currentThread().getId()); Intent intentService = new Intent(this, MyIntentService.class); startService(intentService); break; default: break; } } }
主要介绍了服务的创建、启动、销毁,以及可以自动销毁的服务—
IntentService。
Service实践:后台执行定时服务
实践这部分我只贴出代码如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${relativePackage}.${activityClass}" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
package com.example.servicebestpractice; import java.util.Date; import android.app.AlarmManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import android.util.Log; public class LongRunningService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { Log.d("LongRunningService", "excuted at " + new Date().toString()); } }).start(); AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int anHour = 1 * 1000; long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent i = new Intent(this, AlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi); return super.onStartCommand(intent, flags, startId); } }
package com.example.servicebestpractice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, LongRunningService.class); context.startService(i); } }
package com.example.servicebestpractice; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = new Intent(this, LongRunningService.class); startService(intent); } }
相关文章推荐
- Android 464XLAT
- Android Studio 更新gradle插件
- Android之chromimu和webkit的智能指针的原理
- 基于xmpp openfire smack开发之Android客户端开发[3]
- Android之如何单独编译Android中的模块
- Android之测试Jave接口访问硬件服务
- Android之HAL层编写JNI供Java接口访问
- Android之编写C程序访问Android之驱动程序
- Ubuntu上为Android编写驱动程序
- Android之Dalvik运行过程分析
- Android之Dalvik的进程/线程创建的过程
- Android之Dalvk与JNI注册过程介绍
- Android之View的过程分析
- Android之Activity的框架原理分析
- android 图片点击效果的实现
- Android反编译
- Android之编译系统初始化过程
- Android快捷开关实现
- Android之Service Manager的Binder守护进程
- Android之Binder通信原理