天天看點

android基礎--線程池

        線程池、線程的高效率使用,靈活控制!這裡用最常用的幾種方式來分别實作應用中使用的線程方面的知識,(共寫了兩個不同入口的Activity來分開不同的實作方式,大家可以自行注釋AndroidManifest.xml中的Launch入口或打開注釋)好了,先随便列幾個吧,如:AsyncTask 、Runnable 、Thread、ThreadPool、 Executors等等的使用

一:無大小限制的線程池執行效果如下

android基礎--線程池

二:限制按順序來執行任務的線程池效果如下

android基礎--線程池

三:一個一個任務的執行線程池效果如下(與按順序執行效果是一樣的,隻是内部實作稍有不同)

android基礎--線程池

四:按指定個數來執行任務的線程池效果如下

android基礎--線程池

五:建立一個可在指定時間裡執行任務的線程池,亦可重複執行,不常用,效果與四相同

android基礎--線程池

六:按指定工廠模式來執行的線程池,效果與四、五一樣,但用方式六建立的線程池都有在工廠中指定的線程屬性,

比如:線程名字、是否為使用者線程等等屬性

android基礎--線程池

七:線程池中任務執行時可暫停效果圖如下

android基礎--線程池

八:用Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService關聯實作的效果圖如下

android基礎--線程池

(備注:為了寫文章加注釋還有查找的時候友善,把所有的主類及輔助類以内部類的形式寫到一個.java檔案裡面了,如果朋友們覺得看着亂,不爽的話,可以自行将裡面的類抽取到單獨的.java檔案中,幾分鐘搞定的事!)

方式一(純ExecutorService、AsyncTask、Runnable關聯實作相關檔案如下):

         1.1:主類檔案(Main.java)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

package com.xxxx.threadpooltest;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ThreadFactory;

import android.annotation.TargetApi;

import android.app.Activity;

import android.content.Context;

import android.os.AsyncTask;

import android.os.Build;

import android.os.Bundle;

import android.os.SystemClock;

import android.util.AttributeSet;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.LinearLayout;

import android.widget.ListView;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)

public class Main extends Activity

{

    private static int order = 0;

    // private static final int count = Runtime.getRuntime().availableProcessors() * 3 + 2;

    private static final int count = 10;

    private static ExecutorService singleTaskExecutor = null;

    private static ExecutorService limitedTaskExecutor = null;

    private static ExecutorService allTaskExecutor = null;

    private static ExecutorService scheduledTaskExecutor = null;

    private static ExecutorService scheduledTaskFactoryExecutor = null;

    private List<AsyncTaskTest> mTaskList = null;

    private boolean isCancled = false;

    private boolean isClick = false;

    ThreadFactory tf = Executors.defaultThreadFactory();

    private static class ThreadFactoryTest implements ThreadFactory

    {

        @Override

        public Thread newThread(Runnable r)

        {

            Thread thread = new Thread(r);

            thread.setName("xxxxx_ThreadFactory");

            thread.setDaemon(true); // 将使用者線程變成守護線程,預設false

            return thread;

        }

    }

    static

    {

        singleTaskExecutor = Executors.newSingleThreadExecutor();// 每次隻執行一個線程任務的線程池

        limitedTaskExecutor = Executors.newFixedThreadPool(3);// 限制線程池大小為7的線程池

        allTaskExecutor = Executors.newCachedThreadPool(); // 一個沒有限制最大線程數的線程池

        scheduledTaskExecutor = Executors.newScheduledThreadPool(3);// 一個可以按指定時間可周期性的執行的線程池

        scheduledTaskFactoryExecutor = Executors.newFixedThreadPool(3, new ThreadFactoryTest());// 按指定工廠模式來執行的線程池

        scheduledTaskFactoryExecutor.submit(new Runnable()

        {

            @Override

            public void run()

            {

                Log.i("KKK", "This is the ThreadFactory Test  submit Run! ! ! ");

            }

        });

    };

    @Override

    public void onCreate(Bundle icicle)

    {

        super.onCreate(icicle);

        setContentView(R.layout.demo);

        final ListView taskList = (ListView)findViewById(R.id.task_list);

        taskList.setAdapter(new AsyncTaskAdapter(getApplication(), count));

        taskList.setOnItemClickListener(new OnItemClickListener()

        {

            @Override

            public void onItemClick(AdapterView<?> parent, View view, int position, long id)

            {

                if (position == 0) // 以第一項為例,來測試關閉線程池

                {

                    // allTaskExecutor.shutdown();

                    List<Runnable> unExecRunn = allTaskExecutor.shutdownNow();

                    for (Runnable r : unExecRunn)

                    {

                        Log.i("KKK", "未執行的任務資訊:=" + unExecRunn.toString());

                    }

                    Log.i("KKK", "Is shutdown ? = " + String.valueOf(allTaskExecutor.isShutdown()));

                    allTaskExecutor = null;

                }

                // 以第二項為例來測試是否取消執行的任務

                AsyncTaskTest sat = mTaskList.get(1);

                if (position == 1)

                {

                    if (!isClick)

                    {

                        sat.cancel(true);

                        isCancled = true;

                        isClick = !isClick;

                    }

                    else

                    {

                        sat.cancel(false);

                        isCancled = false;

                        // isClick = false;

                        isClick = !isClick;

                        if (null != sat && sat.getStatus() == AsyncTask.Status.RUNNING)

                        {

                            if (sat.isCancelled())

                            {

                                sat = new AsyncTaskTest(sat.mTaskItem);

                            }

                            else

                            {

                                Toast.makeText(Main.this, "A task is already running, try later", Toast.LENGTH_SHORT).show();

                            }

                        }

                        if (allTaskExecutor == null)

                        {

                            allTaskExecutor = Executors.newCachedThreadPool();

                        }

                        sat.executeOnExecutor(allTaskExecutor); // The task is already running(這也是個異常哦,小心使用! )

                    }

                }

                else

                {

                    sat.cancel(false);

                    isCancled = false;

                    // sat.execute(sat.mTaskItem);

                    // sat.executeOnExecutor(allTaskExecutor);

                }

            }

        });

    }

    private class AsyncTaskAdapter extends BaseAdapter

    {

        private Context mContext;

        private LayoutInflater mFactory;

        private int mTaskCount;

        public AsyncTaskAdapter(Context context, int taskCount)

        {

            mContext = context;

            mFactory = LayoutInflater.from(mContext);

            mTaskCount = taskCount;

            mTaskList = new ArrayList<AsyncTaskTest>(taskCount);

        }

        @Override

        public int getCount()

        {

            return mTaskCount;

        }

        @Override

        public Object getItem(int position)

        {

            return mTaskList.get(position);

        }

        @Override

        public long getItemId(int position)

        {

            return position;

        }

        @Override

        public View getView(int position, View convertView, ViewGroup parent)

        {

            if (convertView == null)

            {

                convertView = mFactory.inflate(R.layout.list_view_item, null);

                AsyncTaskTest task = new AsyncTaskTest((MyListItem)convertView);

                // task.execute();

                // task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);

                // use AsyncTask#THREAD_POOL_EXECUTOR is the same to older version #execute() (less than API 11)

                // but different from newer version of #execute()

                // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

                // task.executeOnExecutor(singleTaskExecutor);

                // task.executeOnExecutor(limitedTaskExecutor);

                task.executeOnExecutor(allTaskExecutor);

                // task.executeOnExecutor(scheduledTaskExecutor);

                // task.executeOnExecutor(scheduledTaskFactoryExecutor);

                mTaskList.add(task);

            }

            return convertView;

        }

    }

    class AsyncTaskTest extends AsyncTask<Void, Integer, Void>

    {

        private MyListItem mTaskItem;

        private String id;

        private AsyncTaskTest(MyListItem item)

        {

            mTaskItem = item;

            if (order < count || order == count)

            {

                id = "執行:" + String.valueOf(++order);

            }

            else

            {

                order = 0;

                id = "執行:" + String.valueOf(++order);

            }

        }

        @Override

        protected void onPreExecute()

        {

            mTaskItem.setTitle(id);

        }

        @Override

        protected void onCancelled()

        {

            super.onCancelled();

        }

        @Override

        protected Void doInBackground(Void... params)

        {

            if (!isCancelled() && isCancled == false) // 這個地方很關鍵,如果不設定标志位的話,直接setCancel(true)是無效的

            {

                int prog = 0;

                while (prog < 101)

                {

                    if ((prog > 0 || prog == 0) && prog < 70) // 小于70%時,加快進度條更新

                    {

                        SystemClock.sleep(100);

                    }

                    else

                    // 大于70%時,減慢進度條更新

                    {

                        SystemClock.sleep(300);

                    }

                    publishProgress(prog); // 更新進度條

                    prog++;

                }

            }

            return null;

        }

        @Override

        protected void onPostExecute(Void result)

        {

        }

        @Override

        protected void onProgressUpdate(Integer... values)

        {

            mTaskItem.setProgress(values[0]); // 設定進度

        }

    }

}

class MyListItem extends LinearLayout

{

    private TextView mTitle;

    private ProgressBar mProgress;

    public MyListItem(Context context, AttributeSet attrs)

    {

        super(context, attrs);

    }

    public MyListItem(Context context)

    {

        super(context);

    }

    public void setTitle(String title)

    {

        if (mTitle == null)

        {

            mTitle = (TextView)findViewById(R.id.task_name);

        }

        mTitle.setText(title);

    }

    public void setProgress(int prog)

    {

        if (mProgress == null)

        {

            mProgress = (ProgressBar)findViewById(R.id.task_progress);

        }

        mProgress.setProgress(prog);

    }

}

1.2:布局檔案

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?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:paddingLeft="10dip"

    android:paddingRight="10dip"

    android:orientation="vertical" >

    <ListView android:id="@+id/task_list"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:divider="#cccccc"

        android:dividerHeight="0.6dip"

        android:footerDividersEnabled="true"

        android:headerDividersEnabled="true" />

</LinearLayout>

方式二(Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService關聯實作的相關檔案如 下):

          2.1:主類檔案(MyRunnableActivity.java)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

package com.xxxxx.threadpooltest;

import java.util.Iterator;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentLinkedQueue;

import java.util.concurrent.ConcurrentMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.ProgressBar;

import android.widget.Toast;

public class MyRunnableActivity extends Activity implements OnClickListener

{

    private ConcurrentLinkedQueue<MyRunnable> taskQueue = null;

    private ConcurrentMap<Future, MyRunnable> taskMap = null;

    private ExecutorService mES = null;

    private Object lock = new Object();

    private boolean isNotify = true;

    private boolean isRuning = true;

    private ProgressBar pb = null;

    private Handler mHandler = null;

    @Override

    protected void onCreate(Bundle savedInstanceState)

    {

        // TODO Auto-generated method stub

        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_runnable_main);

        init();

    }

    public void init()

    {

        pb = (ProgressBar)findViewById(R.id.progressBar1);

        findViewById(R.id.button1).setOnClickListener(this);

        findViewById(R.id.button2).setOnClickListener(this);

        findViewById(R.id.button3).setOnClickListener(this);

        findViewById(R.id.button4).setOnClickListener(this);

        findViewById(R.id.button5).setOnClickListener(this);

        taskQueue = new ConcurrentLinkedQueue<MyRunnable>();

        taskMap = new ConcurrentHashMap<Future, MyRunnable>();

        if (mES == null)

        {

            mES = Executors.newCachedThreadPool();

        }

        // 用于更新ProgressBar進度條

        mHandler = new Handler()

        {

            @Override

            public void handleMessage(Message msg)

            {

                super.handleMessage(msg);

                pb.setProgress(msg.what);

            }

        };

    }

    @Override

    public void onClick(View v)

    {

        switch (v.getId())

        {

            case R.id.button1:

                start();

                break;

            case R.id.button2:

                stop();

                break;

            case R.id.button3:

                reload(new MyRunnable(mHandler));

                break;

            case R.id.button4:

                release();

                break;

            case R.id.button5:

                addTask(new MyRunnable(mHandler));

                break;

            default:

                break;

        }

    }

    private void addTask(final MyRunnable mr)

    {

        mHandler.sendEmptyMessage(0);

        if (mES == null)

        {

            mES = Executors.newCachedThreadPool();

            notifyWork();

        }

        if (taskQueue == null)

        {

            taskQueue = new ConcurrentLinkedQueue<MyRunnable>();

        }

        if (taskMap == null)

        {

            taskMap = new ConcurrentHashMap<Future, MyRunnable>();

        }

        mES.execute(new Runnable()

        {

            @Override

            public void run()

            {

                taskQueue.offer(mr);

                // taskQueue.add(mr);

                notifyWork();

            }

        });

        Toast.makeText(MyRunnableActivity.this, "已添加一個新任務到線程池中 !", 0).show();

    }

    private void release()

    {

        Toast.makeText(MyRunnableActivity.this, "釋放所有占用的資源!", 0).show();

        mHandler.sendEmptyMessage(0);

        isRuning = false;

        Iterator iter = taskMap.entrySet().iterator();

        while (iter.hasNext())

        {

            Map.Entry<Future, MyRunnable> entry = (Map.Entry<Future, MyRunnable>)iter.next();

            Future result = entry.getKey();

            if (result == null)

            {

                continue;

            }

            result.cancel(true);

            taskMap.remove(result);

        }

        if (null != mES)

        {

            mES.shutdown();

        }

        mES = null;

        taskMap = null;

        taskQueue = null;

    }

    private void reload(final MyRunnable mr)

    {

        mHandler.sendEmptyMessage(0);

        if (mES == null)

        {

            mES = Executors.newCachedThreadPool();

            notifyWork();

        }

        if (taskQueue == null)

        {

            taskQueue = new ConcurrentLinkedQueue<MyRunnable>();

        }

        if (taskMap == null)

        {

            taskMap = new ConcurrentHashMap<Future, MyRunnable>();

        }

        mES.execute(new Runnable()

        {

            @Override

            public void run()

            {

                taskQueue.offer(mr);

                // taskQueue.add(mr);

                notifyWork();

            }

        });

        mES.execute(new Runnable()

        {

            @Override

            public void run()

            {

                if (isRuning)

                {

                    MyRunnable myRunnable = null;

                    synchronized (lock)

                    {

                        myRunnable = taskQueue.poll(); // 從線程隊列中取出一個Runnable對象來執行,如果此隊列為空,則調用poll()方法會傳回null

                        if (myRunnable == null)

                        {

                            isNotify = true;

                        }

                    }

                    if (myRunnable != null)

                    {

                        taskMap.put(mES.submit(myRunnable), myRunnable);

                    }

                }

            }

        });

    }

    private void stop()

    {

        Toast.makeText(MyRunnableActivity.this, "任務已被取消!", 0).show();

        for (MyRunnable runnable : taskMap.values())

        {

            runnable.setCancleTaskUnit(true);

        }

    }

    private void start()

    {

        if (mES == null || taskQueue == null || taskMap == null)

        {

            Log.i("KKK", "某資源是不是已經被釋放了?");

            return;

        }

        mES.execute(new Runnable()

        {

            @Override

            public void run()

            {

                if (isRuning)

                {

                    MyRunnable myRunnable = null;

                    synchronized (lock)

                    {

                        // 從線程隊列中取出一個Runnable對象來執行,如果此隊列為空,則調用poll()方法會傳回null

                        myRunnable = taskQueue.poll();

                        if (myRunnable == null)

                        {

                            isNotify = true;

                            // try

                            // {

                            // myRunnable.wait(500);

                            // }

                            // catch (InterruptedException e)

                            // {

                            // e.printStackTrace();

                            // }

                        }

                    }

                    if (myRunnable != null)

                    {

                        taskMap.put(mES.submit(myRunnable), myRunnable);

                    }

                }

            }

        });

    }

    private void notifyWork()

    {

        synchronized (lock)

        {

            if (isNotify)

            {

                lock.notifyAll();

                isNotify = !isNotify;

            }

        }

    }

}

2.2:輔助類(MyRunnable.java)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

package com.xxxxx.threadpooltest;

import android.os.Handler;

import android.os.SystemClock;

import android.util.Log;

public class MyRunnable implements Runnable

{

    private boolean cancleTask = false;

    private boolean cancleException = false;

    private Handler mHandler = null;

    public MyRunnable(Handler handler)

    {

        mHandler = handler;

    }

    @Override

    public void run()

    {

        Log.i("KKK", "MyRunnable  run() is executed!!! ");

        runBefore();

        if (cancleTask == false)

        {

            running();

            Log.i("KKK", "調用MyRunnable run()方法");

        }

        runAfter();

    }

    private void runAfter()

    {

        Log.i("KKK", "runAfter()");

    }

    private void running()

    {

        Log.i("KKK", "running()");

        try

        {

            // 做點有可能會出異常的事情!!!

            int prog = 0;

            if (cancleTask == false && cancleException == false)

            {

                while (prog < 101)

                {

                    if ((prog > 0 || prog == 0) && prog < 70)

                    {

                        SystemClock.sleep(100);

                    }

                    else

                    {

                        SystemClock.sleep(300);

                    }

                    if (cancleTask == false)

                    {

                        mHandler.sendEmptyMessage(prog++);

                        Log.i("KKK", "調用 prog++ = " + (prog));

                    }

                }

            }

        }

        catch (Exception e)

        {

            cancleException = true;

        }

    }

    private void runBefore()

    {

        // TODO Auto-generated method stub

        Log.i("KKK", "runBefore()");

    }

    public void setCancleTaskUnit(boolean cancleTask)

    {

        this.cancleTask = cancleTask;

        Log.i("KKK", "點選了取消任務按鈕 !!!");

        // mHandler.sendEmptyMessage(0);

    }

}

2.3:布局檔案

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

<?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" >

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="horizontal" >

        <Button

            android:id="@+id/button5"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="添加任務" />

        <Button

            android:id="@+id/button1"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="開始任務" />

        <Button

            android:id="@+id/button2"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="取消任務" />

        <Button

            android:id="@+id/button3"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="重新加載" />

        <Button

            android:id="@+id/button4"

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1"

            android:text="釋放資源" />

    </LinearLayout>

    <include layout="@layout/my_runnable_merge"/>

</LinearLayout>

方式一、方式二的全局配置檔案AndroidManifest.xml檔案的配置如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.xxxx.threadpooltest"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="15" />

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="Main"

            android:label="@string/app_name" >

<!--             <intent-filter> -->

<!--                 <action android:name="android.intent.action.MAIN" /> -->

<!--                 <category android:name="android.intent.category.LAUNCHER" /> -->

<!--             </intent-filter> -->

        </activity>

        <activity

            android:name="MyRunnableActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

</manifest>

源碼:http://mzh3344258.blog.51cto.com/1823534/1313611 裡面的附件,WordPress裡面不知道怎麼上傳,大家多見諒吧.

這些代碼中寫的都是一些比較簡單的寫法, 僅僅是使用了線上程中休眠的方式來模拟網絡下載下傳(還是個假象),如果在實際代碼中使用時,尤其在釋放資源這一塊,不要隻是單單釋放了我們自己控制的線程池及其任務,還要将網絡請求的Http也一同銷毀(disconnection)掉哦,這樣才算做到了完美!

如果還有哪位朋友沒有安卓源碼的話,可以到這個位址檢視官方線上的安卓系統源碼:https://github.com/android  

  • 本文固定連結: https://www.xuanyusong.com/archives/2439