thread

来源:互联网 发布:php $a=array_pop 编辑:程序博客网 时间:2024/06/17 02:03

我们知道安卓不能在子线程中进行UI操作,那么我们如何在发送一个子进程的过程中然后进行UI操作呢

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

public static final int UP_DATE=1;

private TextView text;

private Handler handler=new Handler(){

public void handleMessage(Message msg){

switch(msg.what){

case UPDATE_TEXT:

text.setText("Nice to meet you");

break;

default:break;}}};

...

public void onClick(View v){

switch(v.getId)){

case R.id.change_text:

new Thread(new Runnable(){

public void run(){  Message message=new Message();   message.what=UPDATE_TEXT;handler.sendMessage(message);}

还可以使用一种更简单的工具AsyncTask从子线程切换到主线程:这是一个抽象类:有三个参数需要一个子类去继承。

AsyncTask(Params:后台任务传入的参数,Progress:进度单位,Result:对结果进行返回><void,Integer,Boolean>

需要重写的几个方法

1、onPreExecute()后台任务开始之前调用,用于显示一些界面上的初始化操作

2、doInBackground(params...)这个方法中代码都会在子线程中进行,反馈当前任务进度可以调用publishProgress(Progress)

3、onProgressUpdate(Progress)后台任务传递过来的,可以进行UI操作

4、onPostExecute(Result)利用返回结果进行UI操作

添加服务:在example包中添加new service命名为MyService 继承Service

public class MyService extends Service{

public MyService(){}

@Override

public void onCreate(){  super.onCreate()};

@Override public int onStartCommand(Intent intent,int flags,int startId){}

@Override public void Destroy(){super.onDestroy();}

@Override   public IBinder onbind(Intent intent){throw new UnsupportedOperationException("fff");}

启动服务的按键响应方式:Intent startIntent=new Intent(this,MyService.class) ;   startService(startIntent);

停止方式 Intent stopIntent;   stopService(stopIntent);

在服务运行的任何位置调用stopSelf()都能拿使服务自动停止;

活动与服务的联系更紧密就要用到上面的onBind()方法了;

public class MyService extends Service{

private DownloadBinder mBinder=new DownloadBinder();

class DownloadBinder extends Binder{

public void start Download();   public  int getProgress();    public int getProgress();}

@Override   public IBinder onBind(Intent intent){   return mBinder;}}

然后在活动中处理这个:

public class.....{

private MyService.DownloadBinder downloadBinder;

private ServiceConnection connection=new ServiceConnection(){

@Override   public void onServiceDisconnected(ComponentName name){}

@Override    public void onServiceConnected(ComponentName name,IBinder service){

downloadBinder=(MyService.DownloadBinder)service;

downloadBinder.startDownload();

downloadBinder.getProgress();}};

同理bindService 与unbindService 与上面的startService和stopService用法一样;

bindService(bindIntent,connection,BIND_AUTO_CREATE);   unbindService(connection);

在服务中startForeground(1,notification)可以在前台显示通知。

在onStartCommand函数中可以

new Thread(new Runnable(){

public void run(){

stopSelf();

}

}IntentService可以创建异步的,自动停止的服务。

Thread.currentThread().getId();打印当前线程的ID;同时还要记住去androidmanifest里面注册服务<service android:name=".MyIntentService"/>

完整的下载示例:

写文件流FileOutputStream out=openFileOutput(fileName,Activity.MPDE_PRIVATE)重复写入文件会覆盖

out.write(content.getBytes());

out.close()

读文件

FileInputStream in=this.openFileInput(fileName);

byte[] bytes=new byte[1024];

ByteArrayOutputStream arrayout=new....;

String content=new String(arrayout.toByteArray());

showTextView.setText(content);

定义一个回调接口,用于对下载过程中各种状态进行监听和回调

public interface DownloadListener{

void onProgress(int progress);

void onSuccess();

void onFailed();

void onPaused();

void onCanceled();}

public class DownloadTask extends AsyncTask<String,integer,Integer>{

public static final int TYPE_SUCCESS=0;

public static final int TYPE_FAILED=1;

public static final int TYPE_PAUSED=2;

public static final int TYPE_CANCELED=3;

private DownloadListener listener;

private boolean isCanceled=false;

private boolean isPaused=false;

private int lastProgress;

public DownloadTask(DownloadListener listener){

this.listener=listener;}在服务的过程中回调参数。

@Override

protected Integer doInBackground(String ...params){

InputStream is=null;

RandomAccessFile savedFile=null;

File file=null;

try{

long downloadLength=0;

String downloadUrl=params[0];

String fileName=downloadUrl.substring(downloadUrl.lastIndexOf("/"));

String directory=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();

file=new File(directory+fileName);

if (file.exists()){downloadedLength=file.length();}

long contentLength=getContentLength(downloadUrl);

if (contentLength==0){

return TYPE_FAILED;}

else if (contentLength=downloadedLength){

return TYPE_SUCCESS;}

OkHttpClient client=new OkHttpClient();

Request request=new Request.Builder().addHeader("RANGE","bytes="+downloadedLength+"-")

.url(downloadUrl).build();Response response=client.newCall(request).execute();

if (response!=null){

is=response.body().byteStream();

savedFile=new RandomAccessFile(file,"rw");

savedFile.seek(downloadedLength);

byte[] b=new byte[1024];

int total=0;

int len;

while ((len=is.read(b))!=-1){

if (isCancled)   return TYPE_CANCELED;  else if (isPaused)  return TYPE_PAUSED;

else {total+=len;   savedFile.write(b,0,len);   

int progress=(int)((total+downloadedLength)*100/contentLength);

publishProgress(progress);}}

response.body().close;

return TYPE_SUCCESS;}catch(Exception e){  e.printStackTrace();}

finally{try{if (is!=null){  is.close();}   if (savedFile!=null){savedFile.close();}if (isCanceled&&file!=null){file.delete()'}}

catch(Exception e){ e.printStackTrace();}}

return TYPE_FAILED}

@Override

protected  void onProgressUpdate(Integer...values){

int progress=values[0];

if (progress>lastProgress){listener.onProgress(progress);   lastProgress=progress;}}

@Override

protected void onPostExecute(Integer status){

switch(status)   case TYPE_SUCCESS;

listener.onSuccess();

....

}}

public void pauseDownload(){

isPaused =true;}

public void cancelDownload(){   isCanceled=true;}

private long getContentLength(String downloadUrl)throws IOException{

OkHttpClient client=new OkHttpClient();

Request request=new Request.Builder().url(downloadUrl).build();

Response response=client.newCall(request).execute();

if (response!=null&&response.isSuccessful()){

long contentLength=response.body().contentLength();

response.close();

return contentLength();}

return 0;}}


原创粉丝点击