zoukankan      html  css  js  c++  java
  • Service知识点总结

    转载请注明出处:http://blog.csdn.net/krislight/article


            Service可以看作一个后台服务,但并非是开启另外的线程,Service还是在主线程中运行.所以需避免耗时操作。

            如果Service還未啟動,調用startService方法會call Service的onCreate()方法,如果已經啟動會call Service的

    onStartCommand()方法,在onStartCommand()方法最後會返回一個int值代表Service重啟后的行為,該int值含義有

    以下幾種:

    Table 1. Restart options

    Option

    Description

    Service.START_STICKY

    Service is restarted if it gets terminated. Intent data passed to the onStartCommand method is null. Used for services which manages their own state and do not depend on the Intent data.

    Service.START_NOT_STICKY

    Service is not restarted. Used for services which are periodically triggered anyway. The service is only restarted if the runtime has pending startService() calls since the service termination.

    Service.START_REDELIVER_INTENT

    Similar to Service.START_STICKY but the original Intent is re-delivered to the onStartCommand method.

     

    通過Intent.getFlags()方法可以判斷Service是否重啟過,返回START_FLAG_REDELIVERYSTART_FLAG_RETRY代表Service已經重啟過了。

    通過stopService()stopSelf()來停止Service

    如果一個Activity想和Service之間交互通信,使用bindService()來啟動Service

    可以指定android:process屬性將service運行到另一個單獨的進程,如果屬性前面有分號如

    android:process =”:remote”代表該Service針對自身的應用程序私有,如果沒有分號如

    android:process =”remote”代表該Service是共享進程,可以被其他應用程序使用。

    很少指定Service運行在單獨運行在自己的進程,除非你希望將Service與其他應用程序共享。


    IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,

    对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的

    worker thread中处理,不会阻塞应用程序的主线程.

    使用IntentService下載文件實例:

    ①在Acitivity中啟動Service

          

    public class DownloadService extends IntentService {
      private int result = Activity.RESULT_CANCELED;
      public static final String URL = "urlpath";
      public static final String FILENAME = "filename";
      public static final String FILEPATH = "filepath";
      public static final String RESULT = "result";
      public static final String NOTIFICATION = "com.example.android.service.receiver";
    
      public DownloadService() {
        super("DownloadService");
      }
    
      // will be called asynchronously by Android
      @Override
      protected void onHandleIntent(Intent intent) {
        String urlPath = intent.getStringExtra(URL);
        String fileName = intent.getStringExtra(FILENAME);
        File output = new File(Environment.getExternalStorageDirectory(),
            fileName);
        if (output.exists()) {
          output.delete();
        }
    
        InputStream stream = null;
        FileOutputStream fos = null;
        try {
    
          URL url = new URL(urlPath);
          stream = url.openConnection().getInputStream();
          InputStreamReader reader = new InputStreamReader(stream);
          fos = new FileOutputStream(output.getPath());
          int next = -1;
          while ((next = reader.read()) != -1) {
            fos.write(next);
          }
          // successfully finished
          result = Activity.RESULT_OK;
    
        } catch (Exception e) {
          e.printStackTrace();
        } finally {
          if (stream != null) {
            try {
              stream.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
          if (fos != null) {
            try {
              fos.close();
            } catch (IOException e) {
              e.printStackTrace();
            }
          }
        }
        publishResults(output.getAbsolutePath(), result);
      }
    
      private void publishResults(String outputPath, int result) {
        Intent intent = new Intent(NOTIFICATION);
        intent.putExtra(FILEPATH, outputPath);
        intent.putExtra(RESULT, result);
        sendBroadcast(intent);
      }
    }
    

    在XML配置文件中申請權限:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    註冊Service

    <service android:name="com.example.android.service.DownloadService" ></service>


    佈局文件main_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="Download" />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Status: " />
            <TextView
                android:id="@+id/status"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Not started" />
        </LinearLayout>
    </LinearLayout> 
    

    主頁面:

    public class MainActivity extends Activity {
      private TextView textView;
      private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          Bundle bundle = intent.getExtras();
          if (bundle != null) {
            String string = bundle.getString(DownloadService.FILEPATH);
            int resultCode = bundle.getInt(DownloadService.RESULT);
            if (resultCode == RESULT_OK) {
              Toast.makeText(MainActivity.this,
                  "Download complete. Download URI: " + string,
                  Toast.LENGTH_LONG).show();
              textView.setText("Download done");
            } else {
              Toast.makeText(MainActivity.this, "Download failed",
                  Toast.LENGTH_LONG).show();
              textView.setText("Download failed");
            }
          }
        }
      };
    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.status);
      }
    
      @Override
      protected void onResume() {
        super.onResume();
        registerReceiver(receiver, new IntentFilter(DownloadService.NOTIFICATION));
      }
      @Override
      protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
      }
    
      public void onClick(View view) {
        Intent intent = new Intent(this, DownloadService.class);
        // add infos for the service which file to download and where to store
        intent.putExtra(DownloadService.FILENAME, "index.html");
        intent.putExtra(DownloadService.URL,
            "http://www.baidu.com/index.html");
        startService(intent);
        textView.setText("Service started");
      }
    }
    

    這裡Activity與Service交互是通過Activity註冊一個BroadCastReceiver來監聽廣播,啟動Service后,一旦Service完成任務發送廣播,BroadCastReceiver監聽到廣播進行相應的處理。


    再介紹一個例子讓Activity綁定到運作中的Service,這個Service在開機后自動運行,并模擬抓取數據

    先建一個Service:

        

    public class LocalWordService extends Service {
      private final IBinder mBinder = new MyBinder();
      private ArrayList<String> list = new ArrayList<String>();
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
        Random random = new Random();
        if (random.nextBoolean()) {
          list.add("Linux");
        }
        if (random.nextBoolean()) {
          list.add("Android");
        }
        if (random.nextBoolean()) {
          list.add("iPhone");
        }
        if (random.nextBoolean()) {
          list.add("Windows7");
        }
        if (list.size() >= 20) {
          list.remove(0);
        }
        return Service.START_NOT_STICKY;
      }
      @Override
      public IBinder onBind(Intent arg0) {
        return mBinder;
      }
      public class MyBinder extends Binder {
        LocalWordService getService() {
          return LocalWordService.this;
        }
      }
      public List<String> getWordList() {
        return list;
      }
    }
    

    建立一個監聽開機啟動的廣播接收器,該接收器每隔30秒發送啟動Service的廣播: 

    public class MyScheduleReceiver extends BroadcastReceiver {
      // restart service every 30 seconds
      private static final long REPEAT_TIME = 1000 * 30;
      @Override
      public void onReceive(Context context, Intent intent) {
        AlarmManager service = (AlarmManager) context
            .getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, MyStartServiceReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar cal = Calendar.getInstance();
        // start 30 seconds after boot completed
        cal.add(Calendar.SECOND, 30);
        // fetch every 30 seconds
        // InexactRepeating allows Android to optimize the energy consumption
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
            cal.getTimeInMillis(), REPEAT_TIME, pending);
        // service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
        // REPEAT_TIME, pending);
      }
    } 
    

    啟動Service的接收器:

    public class MyStartServiceReceiver extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, LocalWordService.class);
        context.startService(service);
      }
    }
    


    佈局文件mainLayout

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="Update" > 
        </Button>
        <ListView
            android:id="@id/android:list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    </LinearLayout> 
    

    主頁面:

    public class MainActivity extends ListActivity {
      private LocalWordService s;
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wordList = new ArrayList<String>();
        adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, android.R.id.text1,
            wordList);
        setListAdapter(adapter);
      }
    
      @Override
      protected void onResume() {
        super.onResume();
        Intent intent= new Intent(this, LocalWordService.class);
        bindService(intent, mConnection,
            Context.BIND_AUTO_CREATE);
      }
    
      @Override
      protected void onPause() {
        super.onPause();
        unbindService(mConnection);
      }
    
      private ServiceConnection mConnection = new ServiceConnection() {
    
        public void onServiceConnected(ComponentName className, 
            IBinder binder) {
          LocalWordService.MyBinder b = (LocalWordService.MyBinder) binder;
          s = b.getService();
          Toast.makeText(MainActivity.this, "Connected", Toast.LENGTH_SHORT)
              .show();
        }
    
        public void onServiceDisconnected(ComponentName className) {
          s = null;
        }
      };
      private ArrayAdapter<String> adapter;
      private List<String> wordList;
    
      public void onClick(View view) {
        if (s != null) {
          Toast.makeText(this, "Number of elements" + s.getWordList().size(),
              Toast.LENGTH_SHORT).show();
          wordList.clear();
          wordList.addAll(s.getWordList());
          adapter.notifyDataSetChanged();
        }
      }
    }
    
    




  • 相关阅读:
    JVM
    OLAP
    rocketMq学习
    redis的使用小记
    CRT配置端口转发
    冒泡排序
    spring AOP-切面编程
    linux下对jar包和war包进行重新打包
    oracle-sql性能优化
    遍历List,根据子项的某个属性分组
  • 原文地址:https://www.cnblogs.com/krislight1105/p/3748321.html
Copyright © 2011-2022 走看看