使用Service服务后台运行Toast显示小火箭

知识点:

1 使用Service服务后台运行Toast显示小火箭

2 使用子线程更新火箭发射功能

3 使用handle.post在主线程中充当延时函数


1 使用Service服务后台运行Toast显示小火箭

1建立一个Service类,并在AndroidManifest.xml中进行注册:

public class RocketService extends Service


2使用WindowManager设置界面显示参数:

private void InitRocket() {

		mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);

		winWidth = mWM.getDefaultDisplay().getWidth();
		winHeight = mWM.getDefaultDisplay().getHeight();

		params = new WindowManager.LayoutParams();

		params.height = WindowManager.LayoutParams.WRAP_CONTENT;

		params.width = WindowManager.LayoutParams.WRAP_CONTENT;
		params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;

		params.format = PixelFormat.TRANSLUCENT;
		params.type = WindowManager.LayoutParams.TYPE_PHONE; // 需要将类型改为TYPE_PHONE才能移动

		params.gravity = Gravity.LEFT + Gravity.TOP;
		params.setTitle("Toast");

		view_toastrocket = View.inflate(RocketService.this, R.layout.rocket_toast, null);
		ivRocket = (ImageView) view_toastrocket.findViewById(R.id.iv_rocket);

		// 添加view对象
		mWM.addView(view_toastrocket, params);

		view_toastrocket.setOnTouchListener(new OnTouchListener() {

			private int startx;
			private int starty;

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:

					startx = (int) event.getRawX();
					starty = (int) event.getRawY();
					System.out.println("点击图片");
					break;
				case MotionEvent.ACTION_MOVE:
					int endx = (int) event.getRawX();
					int endy = (int) event.getRawY();
					int dx = endx - startx;
					int dy = endy - starty;
					params.x += dx;
					params.y += dy;
					if (params.x < 0) {
						params.x = 0;
					}

					if (params.y < 0) {
						params.y = 0;
					}

					if (params.x > winWidth - view_toastrocket.getWidth()) {
						params.x = winWidth - view_toastrocket.getWidth();
					}

					if (params.y > winHeight - view_toastrocket.getHeight()) {
						params.y = winHeight - view_toastrocket.getHeight();
					}
					mWM.updateViewLayout(view_toastrocket, params); // 更新图片在屏幕上的位置

					startx = (int) event.getRawX();
					starty = (int) event.getRawY();
					break;

				case MotionEvent.ACTION_UP:
					if (params.x > 100 && params.x < 250) {
						if (params.y > 300) {
							sendRocket();
						}
					}
				default:
					break;
				}
				return true;
			}
		});
	}

3 用户抬起时(MotionEvent.ACTION_UP)发射火箭:

if (params.x > 100 && params.x < 250) {
						if (params.y > 300) {
							sendRocket();
						}
					}

4 添加权限:





2 使用子线程更新火箭发射功能

1 创建Thread子线程:

new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
			}
		}.start();


2 使用handler 更新视图

 由于在子线程中无法更新视图(视图只能在主线程中进行更新),所以使用handler的handeMessage接收子线程发送的消息来实现更新界面视图。

 (1)创建一个handler,并重写handlemessage

private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {

			
		};

	};

(2)拼接一个Message发送给handler

Message message = Message.obtain();
					message.arg1 = params.y;
					mHandler.sendMessage(message);


(3)在handleMessage中更新视图:

mWM.updateViewLayout(view_toastrocket, params);

过程:

private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {

			int y = msg.arg1;
			params.y = y;
			mWM.updateViewLayout(view_toastrocket, params);
		};

	};

	protected void sendRocket() {
		// for (int i = 300; i >= 0; i++) {
		// params.y = i;
		// mWM.updateViewLayout(view_toastrocket, params);
		// }
		
		System.out.println("发射火箭!!!");
		new Thread() { // 创建一个子线程进行更新
			@Override
			public void run() {

				System.out.println("子线程");
				params.x = winWidth / 2 - view_toastrocket.getWidth() / 2;
				for (int i = 0; i < 10; i++) {
					params.y = 380 - 38 * i;

					Message message = Message.obtain();
					message.arg1 = params.y;
					mHandler.sendMessage(message);
					// mWM.updateViewLayout(view_toastrocket, params);
					// //无法再子线程中更新视图

					/*
					 * 在主线程中使用thread.sleep会导致主线程阻塞,发生崩溃
					 */
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}.start();

	}

3 使用handle.post在主线程中充当延时函数

new Handler().postDelayed(new Runnable() { //运行在主线程中
			
			@Override
			public void run() {
				finish();				
			}
		}, 1000);

package com.example.rocket2;

import android.R.anim;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.animation.AlphaAnimation;
import android.widget.ImageView;

public class BackGroundActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.background_activity);
		ImageView msmoke = (ImageView)findViewById(R.id.iv_smoke_m);
		ImageView  tsmoke =(ImageView) findViewById(R.id.iv_smoke_t);
		
		AlphaAnimation animi = new AlphaAnimation(0, 1);
		animi.setDuration(1000);
		animi.setFillAfter(true);
		tsmoke.startAnimation(animi);
		msmoke.startAnimation(animi);
		
		new Handler().postDelayed(new Runnable() { //运行在主线程中
			
			@Override
			public void run() {
				finish();				
			}
		}, 1000);
	}
}


你可能感兴趣的:(使用Service服务后台运行Toast显示小火箭)