Andriod学习之Service篇

**

Andriod学习路之Service篇

**

1.简介Service

**
Service适用于没有界面,无需用户干预,且需要长期运行的后台功能,其优先级高于Activity,不会轻易被终止,就算被终止,当资源恢复时,它也会自动恢复运行。
Service可以用于后台服务或进程间通信。
**

2.Service的生命周期

**
启动->onCreate()->onStartCommand()->运行->停止->onDestroy()->关闭
**

3.使用方式

**
使用方式有:启动方式和绑定方式。只有后者才能调用Service对象提供的服务。一般混合使用两种方式。
**

4.服务管理

**
服务管理是指服务的启动、运行和停止。在Service中至少要重写onBind方法,用于服务绑定。服务的启动分为隐式启动和显式启动(与启动activity类似)。
(1)显式启动:
startService(new Intent(this,服务类.class));
其中的“this”指运行环境,可以是其它形式。
(2)隐式启动:
要求在注册服务时声明intent-filter的action属性:


			
				
			
		

启动服务:
startService(服务Intent名)

停止服务:
stopService(服务Intent名)

首次启动服务时,系统运行onCreate()->onStartCommand()(onStart()这个方法已经过期),之后再调用startService(),只调用onStartCommand()。停止服务时会调用onDestroy()方法。

使用服务生成并输出随机数

新建一个Service

Andriod学习之Service篇_第1张图片
新建的Service

 public class MyService extends Service {
        public MyService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
 }

在新建的服务中添加方法

@Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this,"正在执行onCreate",Toast.LENGTH_LONG).show();
    }
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this,"正在执行onStart",Toast.LENGTH_LONG).show();
        int rd=(int)((Math.random()*100)+1);
        String str="生成随机数"+String.valueOf(rd);
        return super.onStartCommand(intent, flags, startId);
    }
@Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this,"正在执行onDestroy",Toast.LENGTH_LONG).show();
    }

然后在activity_main.xml中放两个按钮,分别是启动服务和停止服务按钮


  

接着在MainActivity中编写代码

public class MainActivity extends AppCompatActivity {
    private Intent serviceIntent=null;
    private Button start;
    private Button stop;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start=(Button)findViewById(R.id.start);
        stop=(Button)findViewById(R.id.stop);
        serviceIntent=new Intent(this,MyService.class);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(serviceIntent);
            }
        });
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(serviceIntent);
            }
        });
    }
}

下面就是运行的结果:
当点击启动服务按钮之后得到如下结果
Andriod学习之Service篇_第2张图片
然后点击关闭服务得到如下结果
Andriod学习之Service篇_第3张图片
看到执行方法onDestroy,表明服务已经停止运行。那么我们用服务生成随机数就实现了。

服务内使用线程来生成随机数

首先我们修改上面例子中所建立的服务中的代码或者新建一个服务。

public class MyService extends Service {
    private Thread thread;
    private Runnable bdWork=new Runnable() {
        @Override
        public void run() {
            try {
                while(!Thread.interrupted()){
                    int rd=(int)((Math.random()*100)+1);
                    MainActivity.UpdateGUI(rd);
                    Thread.sleep(1000);
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    };
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this,"正在执行onCreate",Toast.LENGTH_LONG).show();
        thread=new Thread(null,bdWork,"mythread1");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this,"正在执行onStart",Toast.LENGTH_LONG).show();
        if(!thread.isAlive()){
            thread.start();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this,"正在执行onDestroy",Toast.LENGTH_LONG).show();
        thread.interrupt();
    }
}

修改后会发现MainActivity.UpdateGUI(rd)错了,那是因为这事MainActivity当中的方法,我们还没有写,下面我们修改MainActivity中的代码。

public class MainActivity extends AppCompatActivity {
    private Intent serviceIntent=null;
    private Button start;
    private Button stop;
    private static Handler handler=new Handler();
    private static int rd;
    private static TextView tv=null;
    private static Runnable refreshLable=new Runnable() {
        @Override
        public void run() {
            tv.setText(String.valueOf(rd));
        }
    };
    public static void UpdateGUI(int rd){
        MainActivity.rd=rd;
        handler.post(refreshLable);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv=(TextView)findViewById(R.id.tv);
        start=(Button)findViewById(R.id.start);
        stop=(Button)findViewById(R.id.stop);
        serviceIntent=new Intent(this,MyService.class);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(serviceIntent);
            }
        });
        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(serviceIntent);
            }
        });
    }
}

我们要在activity_main.xml原来的基础上加入一个TextView,如下所示


然后我们就可以运行了,如下便是运行的结果:
Andriod学习之Service篇_第4张图片
点击启动服务后上图中测试数据处会一直产生100以内的随机数,如下图所示
Andriod学习之Service篇_第5张图片
点击关闭服务后,随机数不在变化
Andriod学习之Service篇_第6张图片

3.使用绑定加法服务完成两个随机数的加法操作。

服务绑定
这种方法不仅能启动服务,还能获得到服务的连接,通过该连接可以执行服务提供的public方法。

1.我们新建一个服务(Service),然后修改当中的代码

public class MyService extends Service {
    private final IBinder mBinder=new LocalBinder();
    public class LocalBinder extends Binder {
        MyService getService(){
            return MyService.this;
        }
    }
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Toast.makeText(this,"正在绑定MyService",Toast.LENGTH_LONG).show();
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Toast.makeText(this,"取消绑定MyService",Toast.LENGTH_LONG).show();
        return super.onUnbind(intent);
    }

//取随机数
    public int getRandomNumber(){
        int rd=(int)((Math.random()*100)+1);
        return rd;
    }
    //求和
    public int sum(int a,int b){
        return a+b;
    }
}

然后我们写MainActivity中的代码

public class MainActivity extends AppCompatActivity {
    private Button bindService;//绑定服务
    private Button unbindService;//取消绑定服务
    private Button getNumber1;//取随机数1
    private Button getNumber2;//取随机数2
    private Button sum;//求和
    private TextView tv1;//随机数1
    private TextView tv2;//随机数2
    private TextView tvSum;//两随机数的和
    private int a;//随机数1
    private int b;//随机数2
    private MyService myService=null;
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myService = ((MyService.LocalBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            myService = null;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindService=(Button)findViewById(R.id.bindService);
        unbindService=(Button)findViewById(R.id.unbindService);
        getNumber1=(Button)findViewById(R.id.getNumber1);
        getNumber2=(Button)findViewById(R.id.getNumber2);
        sum=(Button)findViewById(R.id.qsum);
        tv1 = (TextView)findViewById(R.id.tv1);
        tv2 = (TextView)findViewById(R.id.tv2);
        tvSum = (TextView)findViewById(R.id.sum);
        final Intent intent = new Intent(this,MyService.class);
        bindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(myService == null){
                    bindService(intent,conn,BIND_AUTO_CREATE);
                }
            }
        });
        unbindService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(conn);
            }
        });
        getNumber1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a=myService.getRandomNumber();
                tv1.setText(String.valueOf(a));
            }
        });
        getNumber2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                b=myService.getRandomNumber();
                tv2.setText(String.valueOf(b));
            }
        });
        sum.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvSum.setText(String.valueOf(myService.sum(a,b)));
            }
        });
    }
}

修改activity_main.xml布局


            

然后我们运行

注意:我们必须先点击绑定服务按钮,若不先绑定服务,那么当你点击当中除绑定服务按钮的任意按钮时,app将会出现闪退情况。

正确结果如下
Andriod学习之Service篇_第7张图片
Andriod学习之Service篇_第8张图片
Andriod学习之Service篇_第9张图片
Andriod学习之Service篇_第10张图片
Andriod学习之Service篇_第11张图片
这次的Andriod学习就到这里了.

你可能感兴趣的:(Andriod学习之旅,Andriod,移动开发,AndriodStudio)