Archive for the ‘一.Android基础篇’ Category

Archive for the ‘1.Android基础篇’ Category
 
<!-- Content -->

本讲内容:Service
1、Service的概念
2、Service的生命周期
3、实例:控制音乐播放的Service

本讲源代码:Android学习指南第十四讲源代码

一、Service的概念

Service是Android程序中四大基础组件之一,它和Activity一样都是Context的子类,只不过它没有UI界面,是在后台运行的组件。

Archive for the ‘一.Android基础篇’ Category

二、Service的生命周期

Service对象不能自己启动,需要通过某个Activity、Service或者其他Context对象来启动。启动的方法有两种,Context.startService和Context.bindService()。两种方式的生命周期是不同的,具体如下所示。

Context.startService方式的生命周期:
启动时,startService –> onCreate() –> onStart()
停止时,stopService –> onDestroy()

Context.bindService方式的生命周期:
绑定时,bindService  -> onCreate() –> onBind()
解绑定时,unbindService –>onUnbind() –> onDestory()

三、实例:控制音乐播放的Service

下面我们用一个可以控制在后台播放音乐的例子来演示刚才所学知识,同学们可以通过该例子可以明显看到通过绑定方式运行的Service在绑定对象被销毁后也被销毁了。

Archive for the ‘一.Android基础篇’ Category

下面把代码分享如下:

1、建立一个新项目名字叫 Lesson14_HelloService,Activity起名叫MainHelloService.java

2、res/layout/main.xml中代码写成

view source
print?
01 < ?xml version="1.0" encoding="utf-8"?>
02 <LINEARLAYOUT android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
03 <TEXTVIEW android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_marginTop="10dp" android:textSize="25sp" android:text="音乐播放服务" />
04 <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="10dp" android:textSize="20sp" android:text="开启音乐播放服务" android:id="@+id/Button01">
05 </BUTTON>
06 <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="10dp" android:textSize="20sp" android:text="停止音乐播放服务" android:id="@+id/Button02">
07 </BUTTON>
08   
09 <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="10dp" android:textSize="20sp" android:text="绑定音乐播放服务" android:id="@+id/Button03">
10 </BUTTON>
11 <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginTop="10dp" android:textSize="20sp" android:text="解绑定音乐播放服务" android:id="@+id/Button04">
12 </BUTTON>
13 </LINEARLAYOUT>

2、在res目录中建立一个raw目录,并把一个音乐文件babayetu.mp3拷贝进来

3、在Activity的同目录新建一个service文件MusicService.java

view source
print?
01 package android.basic.lesson14;
02   
03 import android.app.Service;
04 import android.content.Intent;
05 import android.media.MediaPlayer;
06 import android.os.IBinder;
07 import android.util.Log;
08 import android.widget.Toast;
09   
10 public class MusicService extends Service {
11   
12     //为日志工具设置标签
13     String tag ="MusicService"
14   
15     //定义音乐播放器变量
16     MediaPlayer mPlayer;
17   
18     //其他对象通过bindService方法通知该Service时该方法会被调用
19     @Override
20     public IBinder onBind(Intent intent) {
21         Toast.makeText(this,"MusicService onBind()",Toast.LENGTH_SHORT).show();
22         Log.i(tag, "MusicService onBind()");
23         mPlayer.start();
24         return null;
25     }
26   
27     //其他对象通过unbindService方法通知该Service时该方法会被调用
28     @Override
29     public boolean onUnbind(Intent intent){
30         Toast.makeText(this, "MusicService onUnbind()", Toast.LENGTH_SHORT).show();
31         Log.i(tag, "MusicService onUnbind()");
32         mPlayer.stop();
33         return false;
34     }
35   
36     //该服务不存在需要被创建时被调用,不管startService()还是bindService()都会在启动时调用该方法
37     @Override
38     public void onCreate(){
39         Toast.makeText(this, "MusicService onCreate()", Toast.LENGTH_SHORT).show();
40         //创建一个音乐播放器对象
41         mPlayer=MediaPlayer.create(getApplicationContext(), R.raw.babayetu);
42         //设置可以重复播放
43         mPlayer.setLooping(true);
44         Log.i(tag, "MusicService onCreate()");
45     }
46   
47     //用startService方法调用该服务时,在onCreate()方法调用之后,会调用改方法
48     @Override
49     public void onStart(Intent intent,int startid){
50         Toast.makeText(this,"MusicService onStart",Toast.LENGTH_SHORT).show();
51         Log.i(tag, "MusicService onStart()");
52         mPlayer.start();
53     }
54   
55     //该服务被销毁时调用该方法
56     @Override
57     public void onDestroy(){
58         Toast.makeText(this, "MusicService onDestroy()", Toast.LENGTH_SHORT).show();
59         mPlayer.stop();
60         Log.i(tag, "MusicService onDestroy()");
61     }
62 }


4、MainHelloService.java中的代码:

 

view source
print?
01 package android.basic.lesson14;
02   
03 import android.app.Activity;
04 import android.content.ComponentName;
05 import android.content.Context;
06 import android.content.Intent;
07 import android.content.ServiceConnection;
08 import android.os.Bundle;
09 import android.os.IBinder;
10 import android.util.Log;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 import android.widget.Toast;
15   
16 public class MainHelloService extends Activity {
17   
18     //为日志工具设置标签
19     String tag = "MusicService";
20   
21     /** Called when the activity is first created. */
22     @Override
23     public void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.main);
26   
27         //输出Toast消息和日志记录
28         Toast.makeText(MainHelloService.this, "MainHelloService onCreate", Toast.LENGTH_SHORT).show();
29         Log.i(tag, "MainHelloService onCreate");
30   
31         //定义组件对象
32         Button b1= (Button)findViewById(R.id.Button01);
33         Button b2= (Button)findViewById(R.id.Button02);
34         Button b3= (Button)findViewById(R.id.Button03);
35         Button b4= (Button)findViewById(R.id.Button04);
36   
37          //定义服务链接对象
38          final ServiceConnection conn = new ServiceConnection(){
39   
40             @Override
41             public void onServiceConnected(ComponentName name, IBinder service) {
42                 Toast.makeText(MainHelloService.this, "ServiceConnection onServiceConnected", Toast.LENGTH_SHORT).show();
43                 Log.i(tag, "ServiceConnection onServiceConnected");
44   
45             }
46   
47             @Override
48             public void onServiceDisconnected(ComponentName name) {
49                 Toast.makeText(MainHelloService.this, "ServiceConnection onServiceDisconnected", Toast.LENGTH_SHORT).show();
50                 Log.i(tag, "ServiceConnection onServiceDisconnected");
51   
52             }};
53   
54         //定义点击监听器
55         OnClickListener ocl= new OnClickListener(){
56   
57             @Override
58             public void onClick(View v) {
59                 //显示指定intent所指的对象是个Service
60                 Intent intent = new Intent(MainHelloService.this,android.basic.lesson14.MusicService.class);
61                 switch(v.getId()){
62                 case R.id.Button01:
63                     //开始服务
64                     startService(intent);
65                     break;
66                 case R.id.Button02:
67                     //停止服务
68                     stopService(intent);
69                     break;
70                 case R.id.Button03:
71                     //绑定服务
72                     bindService(intent,conn,Context.BIND_AUTO_CREATE);
73                     break;
74                 case R.id.Button04:
75                     //解除绑定
76                     unbindService(conn);
77                     break;
78                 }
79             }
80         };
81   
82         //绑定点击监听器
83         b1.setOnClickListener(ocl);
84         b2.setOnClickListener(ocl);
85         b3.setOnClickListener(ocl);
86         b4.setOnClickListener(ocl);    
87   
88     }
89   
90     @Override
91     public void onDestroy(){
92         super.onDestroy();
93         Toast.makeText(MainHelloService.this, "MainHelloService onDestroy", Toast.LENGTH_SHORT).show();
94         Log.i(tag, "MainHelloService onDestroy");
95     }
96 }


好了,本讲就到这里。

 
7 Comments

Posted <!-- by Nebulayao -->in 1.Android基础篇

 

第十三讲:用户界面 View(八)

27 Jul

Archive for the ‘一.Android基础篇’ Category

本讲内容:Gallery,GridView

十五、Gallery 画廊

Gallery是一个内部元素可以水平滚动,并且可以把当前选择的子元素定位在它中心的布局组件。

我们还是直接看看例子的运行效果。

Archive for the ‘一.Android基础篇’ Category

下面上代码,相关解释都放在代码里了。

1、建立一个新项目 HelloGallery

2、拷贝wallpaper_0.jpg…wallpaper_9.jpg 10个图片文件到res/drawable目录

3、res/layout/main.xml文件的内容如下:

view source
print?
1 <?xml version="1.0" encoding="utf-8"?>
2 <FRAMELAYOUT android:layout_height="fill_parent" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/FrameLayout01">
3 <IMAGEVIEW android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/ImageView01" android:src="@drawable/wallpaper_0">
4 </IMAGEVIEW>
5   
6 <GALLERY android:layout_height="wrap_content" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/Gallery01" android:spacing="5dp">
7 </GALLERY>
8 </FRAMELAYOUT>

 

其中我们使用FrameLayout来实现叠加效果,使用ImageView来显示大图,Gallery来展示画廊,android:spacing="5dp" 属性则是用来设置元素之间的间隔。

4、在res/values/目录中新建一个attrs.xml内容如下:

view source
print?
1 <?xml version="1.0" encoding="UTF-8"?>
2 <RESOURCES>
3     <DECLARE name="HelloGallery" -styleable>
4         <ATTR name="android:galleryItemBackground" />
5     </DECLARE>
6 </RESOURCES>

 

5、在MainHelloGallery.java中的内容如下:

view source
print?
001 package android.basic.lesson13;
002   
003 import android.app.Activity;
004 import android.content.Context;
005 import android.content.res.TypedArray;
006 import android.os.Bundle;
007 import android.view.View;
008 import android.view.ViewGroup;
009   
010 import android.widget.AdapterView;
011 import android.widget.AdapterView.OnItemClickListener;
012 import android.widget.BaseAdapter;
013 import android.widget.Gallery;
014 import android.widget.ImageView;
015 import android.widget.Toast;
016   
017 public class MainHelloGallery extends Activity {
018   
019     /** Called when the activity is first created. */
020     @Override
021     public void onCreate(Bundle savedInstanceState) {
022         super.onCreate(savedInstanceState);
023         setContentView(R.layout.main);
024   
025         //定义UI组件
026         final ImageView iv= (ImageView)findViewById(R.id.ImageView01);
027         Gallery g = (Gallery) findViewById(R.id.Gallery01);
028   
029         //设置图片匹配器
030         g.setAdapter(new ImageAdapter(this));
031   
032         //设置AdapterView点击监听器,Gallery是AdapterView的子类
033         g.setOnItemClickListener(new OnItemClickListener() {
034   
035             @Override
036             public void onItemClick(AdapterView<?> parent, View view,
037                     int position, long id) {
038                 //显示点击的是第几张图片
039                 Toast.makeText(MainHelloGallery.this, "" + position,
040                         Toast.LENGTH_LONG).show();
041                 //设置背景部分的ImageView显示当前Item的图片
042                 iv.setImageResource(((ImageView)view).getId());
043             }
044         });
045     }
046   
047     //定义继承BaseAdapter的匹配器
048     public class ImageAdapter extends BaseAdapter {
049   
050         //Item的修饰背景
051         int mGalleryItemBackground;
052   
053         //上下文对象
054         private Context mContext;
055   
056         //图片数组
057         private Integer[] mImageIds = { R.drawable.wallpaper_0,
058                 R.drawable.wallpaper_1, R.drawable.wallpaper_2,
059                 R.drawable.wallpaper_3, R.drawable.wallpaper_4,
060                 R.drawable.wallpaper_5, R.drawable.wallpaper_6,
061                 R.drawable.wallpaper_7, R.drawable.wallpaper_8,
062                 R.drawable.wallpaper_9 };
063   
064         //构造方法
065         public ImageAdapter(Context c){
066             mContext = c;
067             //读取styleable资源
068             TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
069             mGalleryItemBackground = a.getResourceId(
070                     R.styleable.HelloGallery_android_galleryItemBackground, 0);
071             a.recycle();
072   
073         }
074   
075         //返回项目数量
076         @Override
077         public int getCount() {
078             return mImageIds.length;
079         }
080   
081         //返回项目
082         @Override
083         public Object getItem(int position) {
084             return position;
085         }
086   
087         //返回项目Id
088         @Override
089         public long getItemId(int position) {
090             return position;
091         }
092   
093         //返回视图
094         @Override
095         public View getView(int position, View convertView, ViewGroup parent) {
096   
097             ImageView iv = new ImageView(mContext);
098             iv.setImageResource(mImageIds[position]);
099             //给生成的ImageView设置Id,不设置的话Id都是-1
100             iv.setId(mImageIds[position]);
101             iv.setLayoutParams(new Gallery.LayoutParams(120, 160));
102             iv.setScaleType(ImageView.ScaleType.FIT_XY);
103             iv.setBackgroundResource(mGalleryItemBackground);
104             return iv;
105         }
106   
107     }
108 }

 

我们点击某一张图片,会把该子元素的图片显示在放在后面一层的ImageView组件中。

有兴趣的同学可以了解一下AdapterView的继承关系:

Archive for the ‘一.Android基础篇’ Category

 

十六、GridView 网格组件