Android中的AsyncTask的使用

多线程之 AsyncTask 使用详解和从源码中深入理解 AsyncTask 机制 前言 AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用; Android之所以提供AsyncTask这个类,就是为了方便我们在后台线程中执行操作,然后将结果发送给主线程,从而在主线程中进行UI更新等操作。在使用AsyncTask时,我们无需关注Thread和Handler,AsyncTask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可; 一、AsyncTask介绍和使用 1、AsyncTask介绍 AsyncTask有四个重要的 阅读详情

在Android中实现异步任务机制有两种方式,Handler和AsyncTask。

Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。关于Handler的相关知识,前面也有所介绍,不清楚的朋友们可以参照一下。

为了简化操作,Android1.5提供了工具类android.os.AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。

先来看看AsyncTask的定义:

  1. public abstract class AsyncTask<Params, Progress, Result> {  

三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替。

一个异步任务的执行一般包括以下几个步骤:

1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。

2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。

3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。

4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。

5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

在使用的时候,有几点需要格外注意:

1.异步任务的实例必须在UI线程中创建。

2.execute(Params... params)方法必须在UI线程中调用。

3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

4.不能在doInBackground(Params... params)中更改UI组件的信息。

5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

接下来,我们来看看如何使用AsyncTask执行异步任务操作,我们先建立一个项目,结构如下:

结构相对简单一些,让我们先看看MainActivity.java的代码:

  1. package com.scott.async;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.InputStream;  
  5.   
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.HttpResponse;  
  8. import org.apache.http.HttpStatus;  
  9. import org.apache.http.client.HttpClient;  
  10. import org.apache.http.client.methods.HttpGet;  
  11. import org.apache.http.impl.client.DefaultHttpClient;  
  12.   
  13. import android.app.Activity;  
  14. import android.os.AsyncTask;  
  15. import android.os.Bundle;  
  16. import android.util.Log;  
  17. import android.view.View;  
  18. import android.widget.Button;  
  19. import android.widget.ProgressBar;  
  20. import android.widget.TextView;  
  21.   
  22. public class MainActivity extends Activity {  
  23.       
  24.     private static final String TAG = "ASYNC_TASK";  
  25.       
  26.     private Button execute;  
  27.     private Button cancel;  
  28.     private ProgressBar progressBar;  
  29.     private TextView textView;  
  30.       
  31.     private MyTask mTask;  
  32.       
  33.     @Override  
  34.     public void onCreate(Bundle savedInstanceState) {  
  35.         super.onCreate(savedInstanceState);  
  36.         setContentView(R.layout.main);  
  37.           
  38.         execute = (Button) findViewById(R.id.execute);  
  39.         execute.setOnClickListener(new View.OnClickListener() {  
  40.             @Override  
  41.             public void onClick(View v) {  
  42.                 //注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常  
  43.                 mTask = new MyTask();  
  44.                 mTask.execute("http://www.baidu.com");  
  45.                   
  46.                 execute.setEnabled(false);  
  47.                 cancel.setEnabled(true);  
  48.             }  
  49.         });  
  50.         cancel = (Button) findViewById(R.id.cancel);  
  51.         cancel.setOnClickListener(new View.OnClickListener() {  
  52.             @Override  
  53.             public void onClick(View v) {  
  54.                 //取消一个正在执行的任务,onCancelled方法将会被调用  
  55.                 mTask.cancel(true);  
  56.             }  
  57.         });  
  58.         progressBar = (ProgressBar) findViewById(R.id.progress_bar);  
  59.         textView = (TextView) findViewById(R.id.text_view);  
  60.           
  61.     }  
  62.       
  63.     private class MyTask extends AsyncTask<String, Integer, String> {  
  64.         //onPreExecute方法用于在执行后台任务前做一些UI操作  
  65.         @Override  
  66.         protected void onPreExecute() {  
  67.             Log.i(TAG, "onPreExecute() called");  
  68.             textView.setText("loading...");  
  69.         }  
  70.           
  71.         //doInBackground方法内部执行后台任务,不可在此方法内修改UI  
  72.         @Override  
  73.         protected String doInBackground(String... params) {  
  74.             Log.i(TAG, "doInBackground(Params... params) called");  
  75.             try {  
  76.                 HttpClient client = new DefaultHttpClient();  
  77.                 HttpGet get = new HttpGet(params[0]);  
  78.                 HttpResponse response = client.execute(get);  
  79.                 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  80.                     HttpEntity entity = response.getEntity();  
  81.                     InputStream is = entity.getContent();  
  82.                     long total = entity.getContentLength();  
  83.                     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  84.                     byte[] buf = new byte[1024];  
  85.                     int count = 0;  
  86.                     int length = -1;  
  87.                     while ((length = is.read(buf)) != -1) {  
  88.                         baos.write(buf, 0, length);  
  89.                         count += length;  
  90.                         //调用publishProgress公布进度,最后onProgressUpdate方法将被执行  
  91.                         publishProgress((int) ((count / (float) total) * 100));  
  92.                         //为了演示进度,休眠500毫秒  
  93.                         Thread.sleep(500);  
  94.                     }  
  95.                     return new String(baos.toByteArray(), "gb2312");  
  96.                 }  
  97.             } catch (Exception e) {  
  98.                 Log.e(TAG, e.getMessage());  
  99.             }  
  100.             return null;  
  101.         }  
  102.           
  103.         //onProgressUpdate方法用于更新进度信息  
  104.         @Override  
  105.         protected void onProgressUpdate(Integer... progresses) {  
  106.             Log.i(TAG, "onProgressUpdate(Progress... progresses) called");  
  107.             progressBar.setProgress(progresses[0]);  
  108.             textView.setText("loading..." + progresses[0] + "%");  
  109.         }  
  110.           
  111.         //onPostExecute方法用于在执行完后台任务后更新UI,显示结果  
  112.         @Override  
  113.         protected void onPostExecute(String result) {  
  114.             Log.i(TAG, "onPostExecute(Result result) called");  
  115.             textView.setText(result);  
  116.               
  117.             execute.setEnabled(true);  
  118.             cancel.setEnabled(false);  
  119.         }  
  120.           
  121.         //onCancelled方法用于在取消执行中的任务时更改UI  
  122.         @Override  
  123.         protected void onCancelled() {  
  124.             Log.i(TAG, "onCancelled() called");  
  125.             textView.setText("cancelled");  
  126.             progressBar.setProgress(0);  
  127.               
  128.             execute.setEnabled(true);  
  129.             cancel.setEnabled(false);  
  130.         }  
  131.     }  
  132. }  

布局文件main.xml代码如下:

[xhtml] view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.     <Button  
  7.         android:id="@+id/execute"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="execute"/>  
  11.     <Button  
  12.         android:id="@+id/cancel"  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:enabled="false"  
  16.         android:text="cancel"/>  
  17.     <ProgressBar   
  18.         android:id="@+id/progress_bar"   
  19.         android:layout_width="fill_parent"   
  20.         android:layout_height="wrap_content"   
  21.         android:progress="0"  
  22.         android:max="100"  
  23.         style="?android:attr/progressBarStyleHorizontal"/>  
  24.     <ScrollView  
  25.         android:layout_width="fill_parent"   
  26.         android:layout_height="wrap_content">  
  27.         <TextView  
  28.             android:id="@+id/text_view"  
  29.             android:layout_width="fill_parent"   
  30.             android:layout_height="wrap_content"/>  
  31.     </ScrollView>  
  32. </LinearLayout>  

因为需要访问网络,所以我们还需要在AndroidManifest.xml中加入访问网络的权限:

[xhtml] view plain copy
  1. <uses-permission android:name="android.permission.INTERNET"/>  

我们来看一下运行时的界面:

以上几个截图分别是初始界面、执行异步任务时界面、执行成功后界面、取消任务后界面。执行成功后,整个过程日志打印如下:

如果我们在执行任务时按下了“cancel”按钮,日志打印如下:

可以看到onCancelled()方法将会被调用,onPostExecute(Result result)方法将不再被调用。

上面介绍了AsyncTask的基本应用,有些朋友也许会有疑惑,AsyncTask内部是怎么执行的呢,它执行的过程跟我们使用Handler又有什么区别呢?答案是:AsyncTask是对Thread+Handler良好的封装,在android.os.AsyncTask代码里仍然可以看到Thread和Handler的踪迹。下面就向大家详细介绍一下AsyncTask的执行原理。

我们先看一下AsyncTask的大纲视图:

我们可以看到关键几个步骤的方法都在其中,doInBackground(Params... params)是一个抽象方法,我们继承AsyncTask时必须覆写此方法;onPreExecute()、onProgressUpdate(Progress... values)、onPostExecute(Result result)、onCancelled()这几个方法体都是空的,我们需要的时候可以选择性的覆写它们;publishProgress(Progress... values)是final修饰的,不能覆写,只能去调用,我们一般会在doInBackground(Params... params)中调用此方法;另外,我们可以看到有一个Status的枚举类和getStatus()方法,Status枚举类代码段如下:

  1.         //初始状态  
  2.     private volatile Status mStatus = Status.PENDING;  
  3.       
  4.     public enum Status {  
  5.         /** 
  6.          * Indicates that the task has not been executed yet. 
  7.          */  
  8.         PENDING,  
  9.         /** 
  10.          * Indicates that the task is running. 
  11.          */  
  12.         RUNNING,  
  13.         /** 
  14.          * Indicates that {@link AsyncTask#onPostExecute} has finished. 
  15.          */  
  16.         FINISHED,  
  17.     }  
  18.   
  19. /** 
  20.      * Returns the current status of this task. 
  21.      * 
  22.      * @return The current status. 
  23.      */  
  24.     public final Status getStatus() {  
  25.         return mStatus;  
  26.     }  

可以看到,AsyncTask的初始状态为PENDING,代表待定状态,RUNNING代表执行状态,FINISHED代表结束状态,这几种状态在AsyncTask一次生命周期内的很多地方被使用,非常重要。

介绍完大纲视图相关内容之后,接下来,我们会从execute(Params... params)作为入口,重点分析一下AsyncTask的执行流程,我们来看一下execute(Params... params)方法的代码段:

  1. public final AsyncTask<Params, Progress, Result> execute(Params... params) {  
  2.         if (mStatus != Status.PENDING) {  
  3.             switch (mStatus) {  
  4.                 case RUNNING:  
  5.                     //如果该任务正在被执行则抛出异常  
  6.                     //值得一提的是,在调用cancel取消任务后,状态仍未RUNNING  
  7.                     throw new IllegalStateException("Cannot execute task:"  
  8.                             + " the task is already running.");  
  9.                 case FINISHED:  
  10.                     //如果该任务已经执行完成则抛出异常  
  11.                     throw new IllegalStateException("Cannot execute task:"  
  12.                             + " the task has already been executed "  
  13.                             + "(a task can be executed only once)");  
  14.             }  
  15.         }  
  16.           
  17.         //改变状态为RUNNING  
  18.         mStatus = Status.RUNNING;  
  19.   
  20.         //调用onPreExecute方法  
  21.         onPreExecute();  
  22.   
  23.         mWorker.mParams = params;  
  24.         sExecutor.execute(mFuture);  
  25.   
  26.         return this;  
  27.     }  

代码中涉及到三个陌生的变量:mWorker、sExecutor、mFuture,我们也会看一下他们的庐山真面目:

关于sExecutor,它是java.util.concurrent.ThreadPoolExecutor的实例,用于管理线程的执行。代码如下:

  1. private static final int CORE_POOL_SIZE = 5;  
  2.    private static final int MAXIMUM_POOL_SIZE = 128;  
  3.    private static final int KEEP_ALIVE = 10;  
  4.   
  5. //新建一个队列用来存放线程  
  6.    private static final BlockingQueue<Runnable> sWorkQueue =  
  7.            new LinkedBlockingQueue<Runnable>(10);  
  8. //新建一个线程工厂  
  9.    private static final ThreadFactory sThreadFactory = new ThreadFactory() {  
  10.        private final AtomicInteger mCount = new AtomicInteger(1);  
  11.     //新建一个线程  
  12.        public Thread newThread(Runnable r) {  
  13.            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());  
  14.        }  
  15.    };  
  16. //新建一个线程池执行器,用于管理线程的执行  
  17.    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,  
  18.            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);  

mWorker实际上是AsyncTask的一个的抽象内部类的实现对象实例,它实现了Callable<Result>接口中的call()方法,代码如下:

  1. private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {  
  2.         Params[] mParams;  
  3.     }  

而mFuture实际上是java.util.concurrent.FutureTask的实例,下面是它的FutureTask类的相关信息:

  1. /** 
  2.  * A cancellable asynchronous computation. 
  3.  * ... 
  4.  */  
  5. public class FutureTask<V> implements RunnableFuture<V> {  
  1. public interface RunnableFuture<V> extends Runnable, Future<V> {  
  2.     /** 
  3.      * Sets this Future to the result of its computation 
  4.      * unless it has been cancelled. 
  5.      */  
  6.     void run();  
  7. }  

可以看到FutureTask是一个可以中途取消的用于异步计算的类。

下面是mWorker和mFuture实例在AsyncTask中的体现:

  1.    private final WorkerRunnable<Params, Result> mWorker;  
  2.    private final FutureTask<Result> mFuture;  
  3.   
  4. public AsyncTask() {  
  5.        mWorker = new WorkerRunnable<Params, Result>() {  
  6.            //call方法被调用后,将设置优先级为后台级别,然后调用AsyncTask的doInBackground方法  
  7.         public Result call() throws Exception {  
  8.                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
  9.                return doInBackground(mParams);  
  10.            }  
  11.        };  
  12.   
  13.     //在mFuture实例中,将会调用mWorker做后台任务,完成后会调用done方法  
  14.        mFuture = new FutureTask<Result>(mWorker) {  
  15.            @Override  
  16.            protected void done() {  
  17.                Message message;  
  18.                Result result = null;  
  19.   
  20.                try {  
  21.                    result = get();  
  22.                } catch (InterruptedException e) {  
  23.                    android.util.Log.w(LOG_TAG, e);  
  24.                } catch (ExecutionException e) {  
  25.                    throw new RuntimeException("An error occured while executing doInBackground()",  
  26.                            e.getCause());  
  27.                } catch (CancellationException e) {  
  28.                 //发送取消任务的消息  
  29.                    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,  
  30.                            new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));  
  31.                    message.sendToTarget();  
  32.                    return;  
  33.                } catch (Throwable t) {  
  34.                    throw new RuntimeException("An error occured while executing "  
  35.                            + "doInBackground()", t);  
  36.                }  
  37.   
  38.             //发送显示结果的消息  
  39.                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,  
  40.                        new AsyncTaskResult<Result>(AsyncTask.this, result));  
  41.                message.sendToTarget();  
  42.            }  
  43.        };  
  44.    }  

 我们看到上面的代码中,mFuture实例对象的done()方法中,如果捕捉到了CancellationException类型的异常,则发送一条“MESSAGE_POST_CANCEL”的消息;如果顺利执行,则发送一条“MESSAGE_POST_RESULT”的消息,而消息都与一个sHandler对象关联。这个sHandler实例实际上是AsyncTask内部类InternalHandler的实例,而InternalHandler正是继承了Handler,下面我们来分析一下它的代码:

  1. private static final int MESSAGE_POST_RESULT = 0x1; //显示结果  
  2.    private static final int MESSAGE_POST_PROGRESS = 0x2;    //更新进度  
  3.    private static final int MESSAGE_POST_CANCEL = 0x3;  //取消任务  
  4.   
  5.    private static final InternalHandler sHandler = new InternalHandler();  
  6.   
  7. private static class InternalHandler extends Handler {  
  8.        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})  
  9.        @Override  
  10.        public void handleMessage(Message msg) {  
  11.            AsyncTaskResult result = (AsyncTaskResult) msg.obj;  
  12.            switch (msg.what) {  
  13.                case MESSAGE_POST_RESULT:  
  14.                    // There is only one result  
  15.                 //调用AsyncTask.finish方法  
  16.                    result.mTask.finish(result.mData[0]);  
  17.                    break;  
  18.                case MESSAGE_POST_PROGRESS:  
  19.                    //调用AsyncTask.onProgressUpdate方法  
  20.                 result.mTask.onProgressUpdate(result.mData);  
  21.                    break;  
  22.                case MESSAGE_POST_CANCEL:  
  23.                 //调用AsyncTask.onCancelled方法  
  24.                    result.mTask.onCancelled();  
  25.                    break;  
  26.            }  
  27.        }  
  28.    }  

我们看到,在处理消息时,遇到“MESSAGE_POST_RESULT”时,它会调用AsyncTask中的finish()方法,我们来看一下finish()方法的定义:

  1. private void finish(Result result) {  
  2.         if (isCancelled()) result = null;  
  3.         onPostExecute(result);  //调用onPostExecute显示结果  
  4.         mStatus = Status.FINISHED;  //改变状态为FINISHED  
  5.     }  

原来finish()方法是负责调用onPostExecute(Result result)方法显示结果并改变任务状态的啊。

另外,在mFuture对象的done()方法里,构建一个消息时,这个消息包含了一个AsyncTaskResult类型的对象,然后在sHandler实例对象的handleMessage(Message msg)方法里,使用下面这种方式取得消息中附带的对象:

  1. AsyncTaskResult result = (AsyncTaskResult) msg.obj;  

这个AsyncTaskResult究竟是什么呢,它又包含什么内容呢?其实它也是AsyncTask的一个内部类,是用来包装执行结果的一个类,让我们来看一下它的代码结构:

  1. @SuppressWarnings({"RawUseOfParameterizedType"})  
  2. private static class AsyncTaskResult<Data> {  
  3.     final AsyncTask mTask;  
  4.     final Data[] mData;  
  5.   
  6.     AsyncTaskResult(AsyncTask task, Data... data) {  
  7.         mTask = task;  
  8.         mData = data;  
  9.     }  
  10. }  

看以看到这个AsyncTaskResult封装了一个AsyncTask的实例和某种类型的数据集,我们再来看一下构建消息时的代码:

  1. //发送取消任务的消息  
  2. message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,  
  3.         new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));  
  4. message.sendToTarget();  
  1. //发送显示结果的消息  
  2. message = sHandler.obtainMessage(MESSAGE_POST_RESULT,  
  3.          new AsyncTaskResult<Result>(AsyncTask.this, result));  
  4. message.sendToTarget();  

在处理消息时是如何使用这个对象呢,我们再来看一下:

  1. result.mTask.finish(result.mData[0]);  
  1. result.mTask.onProgressUpdate(result.mData);  

概括来说,当我们调用execute(Params... params)方法后,execute方法会调用onPreExecute()方法,然后由ThreadPoolExecutor实例sExecutor执行一个FutureTask任务,这个过程中doInBackground(Params... params)将被调用,如果被开发者覆写的doInBackground(Params... params)方法中调用了publishProgress(Progress... values)方法,则通过InternalHandler实例sHandler发送一条MESSAGE_POST_PROGRESS消息,更新进度,sHandler处理消息时onProgressUpdate(Progress... values)方法将被调用;如果遇到异常,则发送一条MESSAGE_POST_CANCEL的消息,取消任务,sHandler处理消息时onCancelled()方法将被调用;如果执行成功,则发送一条MESSAGE_POST_RESULT的消息,显示结果,sHandler处理消息时onPostExecute(Result result)方法被调用。

经过上面的介绍,相信朋友们都已经认识到AsyncTask的本质了,它对Thread+Handler的良好封装,减少了开发者处理问题的复杂度,提高了开发效率,希望朋友们能多多体会一下。

安卓Android开发:使用Executor线程池代替AsyncTask进行异步操作 本文介绍了如何使用Executor线程池来代替AsyncTask进行异步操作,并且提供了完整的封装类,来模拟AsyncTask,并提供与AsyncTask一致的使用方式。 阅读详情

相关推荐

使用详解:Android AsyncTask编程指南

AsyncTask是Android提供的一个抽象类,用于在后台线程执行耗时任务,同时在主线程上更新UI。通常情况下,我们可以在预备阶段做一些初始化操作,然后在后台执行阶段处理耗时任务,最后在后台执行结果处理阶段更新UI。在Android开发中,AsyncTask是一个强大的工具,用于在后台执行耗时操作并在主线程上更新UI。在新的Android开发中,建议使用更现代化的异步任务处理方式,如Kotlin协程或Java的Executor框架。方法,该方法在后台线程上执行耗时任务,不可在该方法中更新UI。

PixelNinja的博客 254

Android AsyncTask(线程间通信)

1.AsyncTask 在Android中我们可以通过Thread+Handler实现多线程通信,一种经典的使用场景是:在新线程中进行耗时操作,当任务完成后通过Handler向主线程发送Message,这样主线程的Handler在收到该Message之后就可以进行更新UI的操作。上述场景中需要分别在Thread和Handler中编写代码逻辑,为了使得代码更加统一,我们可以使用AsyncTask类。 AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。

zenmela2011的专栏 6742

Android最全最简单的异步任务AsyncTask使用解析

Android最全最简单的异步任务AsyncTask使用解析.一步到位彻底理解异步任务。

Android AsyncTask 详解

将复杂工作异步化、线程化对于Android 的性能的提高起到了很重要的作用,Android 框架为开发提供了很多辅助程序,这一篇着重分析Android AsyncTask的原理。

私房菜 6810

Java开发的企业排班系统

Java开发的企业排班系统,用了springboot框架,人脸识别是采用百度接口的方式实现

自学网站s.jf3q.com,菜鸟的成长之路 6011

ROS2 Nav2实战:解决rviz2显示no map received的3种实用方法(附详细步骤)

本文针对ROS2 Nav2导航栈中rviz2显示“no map received”的常见问题,提供了三种核心解决方案。深入剖析了问题根源在于ROS2生命周期节点管理、QoS策略不匹配及坐标系设置错误,并分别通过手动配置流程、集成生命周期管理器以及调优QoS策略与固化rviz2配置,给出了详细的实战步骤,确保地图数据可靠显示。

j0k1l2m3n的博客 421

详解Android中AsyncTask的使用

在Android中实现异步任务机制有两种方式,Handler和AsyncTask。Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。关于Handler的相关知识,前面也有所介绍,不清楚的朋友们可以参照一下。

LiuHe 39万+

特斯拉 Model 3解析(八)全面拆解特斯拉自动驾驶大脑:AP控制器硬核技术解析

算力极限:双FSD = 144 TOPS,专为AI推理优化。存储架构:LPDDR4 + NAND + NOR,保证高速/可靠启动。通信架构:以太网传视频,CAN传控制,TSN保障实时性。感知输入:多路摄像头 + 高速SerDes,满足全景感知。电源设计:功率模块+被动元件海洋,稳定性优先。功能安全:双芯片冗余 + GPS + 紧急呼叫,容错率极高。🎯 在我看来,特斯拉AP控制器就是一台“车载超算”,它在电源设计、存储架构和功能安全上远超一般新势力方案。

weixin_43199439的博客 1438

安卓—— 详解Android中AsyncTask的使用

原文链接:http://blog.youkuaiyun.com/liuhe688/article/details/6532519 在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例

Abby同学思考的地方 383

超详细Tokenizer——文本训练数据预处理

Tokenizer是Keras库中的一个文本处理工具,它用于将文本分词并构建词汇表,同时将文本映射到整数序列。这对于自然语言处理任务非常有用,例如文本分类、情感分析、机器翻译等。

halo的博客 3700

EU 2021/646 eCall工程拆解:MSD、测试模式与型式核准

紧急呼叫系统(eCall)是车载通信中面向事故救援的安全功能,其原理是在碰撞或人工触发后,通过蜂窝网络向公共安全应答点发送最小数据集(MSD),并建立语音链路。技术价值在于缩短救援响应时间、提升事故后生存率,应用场景覆盖乘用车、轻型商用车及车载T-Box等前装通信模块。面向欧盟市场时,EU 2021/646把eCall从安装要求推进到型式核准测试,关注触发链路、备用电源、GNSS定位、MSD字段、音频质量与回拨能力。工程落地需要围绕测试模式、字段校验、配置管理和送检样件建立可交付合规方案。

weixin_31815843的博客 206

Android中AsyncTask使用详解

在Android中我们可以通过Thread+Handler实现多线程通信,一种经典的使用场景是:在新线程中进行耗时操作,当任务完成后通过Handler向主线程发送Message,这样主线程的Handler在收到该Message之后就可以进行更新UI的操作。上述场景中需要分别在Thread和Handler中编写代码逻辑,为了使得代码更加统一,我们可以使用AsyncTask类。AsyncTask是And

孙群 5万+

【nvidia-B200】实际生产报错NVRM: nvAssertFailedNoLog: Assertion failed: pIOVAS != NULL @ io_vaspace.c:601

升级 NVIDIA 驱动到 R545/R550 数据中心版本(解决 IOVA bug,这是性能差的根本原因);重启服务器(清理驱动残留资源,消除日志中的 NVRM 错误);验证 NVLink/PCIe 链路(确保 8 卡互联使用高速链路,而非单卡 PCIe 共享带宽)。完成这 3 步后,ncccl-test的all_reduce带宽应能提升至100GB/s 以上(取决于服务器的 NVLink/NVSwitch 配置),恢复正常性能。

jundao1997的专栏 646

Android——AsyncTask使用

前言 在Android中我们可以通过Thread+Handler实现多线程通信,同时我们还可以通过AsyncTask来实现多线程通信,而AsyncTask内部封装了Thread和Handler,可以让我们在后台进行计算并且把计算的结果及时更新到UI上,是Android提供的轻量级的异步类。 一、什么是AsyncTask? AsyncTask是Android提供的轻量级(实现代码量少)的...

lzq33521的博客 344

车辆网络安全ISO/SAE 21434解读(一)概述

ISO/SAE 21434 《道路车辆 网络安全工程》是SAE和ISO共同制定的一项针对道路车辆的网络安全标准,它是一个面向汽车行业全供应链(OEM及各级供应商)的车辆网络安全管理指导文件

xiaoxiabang的博客 8420

【异常】Claude Code 400错误(Extra inputs are not permitted)解决方案

摘要:Claude Code 2.0.37+版本因API请求包含未支持的custom.input_examples参数导致400错误,使核心功能失效。解决方案是降级至稳定版v2.0.32:先卸载当前版本(npm uninstall -g @anthropic-ai/claude-code),再安装指定版本(npm install -g @anthropic-ai/claude-code@2.0.32),最后验证请求是否恢复正常。该问题确认在v2.0.32版本不存在。(148字)

奶爸的编程之路,也就一周冷个三天 2036

android中AsyncTask的使用

android中AsyncTask异步任务的使用 1.关于AsyncTask 在android中实现异步任务有两种方法:一种为通过多线程Thread配合Handler实现,另一种就是通过android为我们提供的AsyncTask类实现。AsyncTask使得编写异步任务相比通过多线程方式更加简单。 public abstract class AsyncTask extends Obj

Duan的博客 578

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

安卓中AsyncTask的基本使用

安卓中AsyncTask的基本使用 使用场景介绍 在安卓开发中,我们经常需要访问互联网资源,这些访问是都需要在后台线程中去完成的,因为安卓的UI线程不允许执行耗时任务。然而,后台线程是不可以修改安卓的UI的,所以我们一般使用Handler去修改UI,这需要我们自己去创建新的线程。其实安卓中已经给我们提供好了一个AsyncTask类,这个类就用用来处理耗时任务的,所以我们使用这...

dianmocan8831的博客 147

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

关于正确使用Android AsyncTask学习整理

关于正确使用Android AsyncTask学习整理这里写链接内容

Charles_ZhuYifei的专栏 470

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

一文详解 Android asynctask使用方式(一)

AsyncTask在各版本中源码的实现方式不用,但有时我们又需要用到AsyncTask,那我们该怎么使用它呢?

bjxiaxueliang的CODING小栈 838

Android开发——AsyncTask的使用以及源码解析

1.AsyncTask使用介绍 AsyncTask封装了Thread和Handler,通过AsyncTask可以很方便地在执行完后台任务后更新UI。如果不太清楚Android的Handler机制,可以查看此篇Android消息机制详解。 下面是一个使用AsyncTask的实例,利用网络下载某URL里的字符串,以模拟耗时任务。在下载过程中,会通过进度条对话框向用户展示进度。在完成任务后将字...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1万+

使用Kotlin的Android AsyncTask

In this tutorial, we’ll learn and implement AsyncTask using Kotlin in our Android Application. 在本教程中,我们将在Android应用程序中使用Kotlin学习和实现AsyncTask。 什么是Android AsyncTask? (What is Android AsyncTask?) Androi...

从零开始的教程世界 2451

Android中AsyncTask的使用解析

在日常开发中我们经常需要用到子线程去处理一些相对耗时的任务,例如网络请求、数据库操作、复杂计算。并在任务完成的时候对UI进行更新,对于这种需求,官方给开发者提供了两种方式:Handler以及AsyncTask。 对于Handler来说,我们每次使用都需要创建一个新的线程,但如果耗时的操作太多,那么我们需要开启太多的子线程,这样就会给系统带来巨大的负担,也会影响程序的性能。在这种情况下我们就可以考虑...

倚栏静望的博客 553

Android中AsyncTask使用

一、AsyncTask的作用: 代替Thread+Handler的组合,使创建异步任务变得简单。 AsyncTask执行后台操作,并在用户界面上发布结果,而不必处理线程。   二、AsyncTask的定义: public abstract class AsyncTask extends Object AsyncTask必须子类可以使用。子类将覆盖至少一个方法

小告白的专栏 504

『ANDROID』AsyncTask的使用注意事项

AsyncTask的使用注意事项 前面的文章曾建议使用AsyncTask而不是使用Thread,但是AsyncTask似乎又有它的限制,这就要根据具体的需求情况而选择合适的工具,No Silver Bullet。下面是一些建议: 改善你的设计,少用异步处理 线程的开销是非常大的,同时异步处理也容易出错,难调试,难维护,所以改善你的设计,尽可能的少用异步。对于一般性的数据库

fallenink的专栏 890
上一篇: Android http请求代码
下一篇: mysql的加密方法
yesjava
博客等级 码龄19年 69粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值