Fox*_*Fox 667 android android-asynctask
我正在阅读AsyncTask,我尝试了下面的简单程序.但它似乎没有用.我怎样才能使它工作?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Void... values) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
我只是想在后台进程中在5秒后更改标签.
这是我的main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="@+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
Sur*_*gch 764
我的完整答案就在这里,但这里有一个解释性图片,以补充本页面上的其他答案.对我来说,了解所有变量的去向是最开始时最令人困惑的部分.

Gra*_*ith 691
好的,你试图通过另一个线程访问GUI.这主要是不好的做法.
AsyncTask执行doInBackground()另一个线程内部的所有内容,该线程无法访问您的视图所在的GUI.
preExecute()并且postExecute()在这个新线程中发生繁重之前和之后,您可以访问GUI,甚至可以将长操作的结果传递postExecute()给后来显示任何处理结果.
请参阅稍后更新TextView的这些行:
TextView txt = findViewById(R.id.output);
txt.setText("Executed");
Run Code Online (Sandbox Code Playgroud)
把它们放进去 onPostExecute()
然后,您将在doInBackground完成后看到TextView文本已更新.
编辑:我注意到你的onClick监听器没有检查是否已选择哪个View.我发现最简单的方法是通过switch语句.我在下面编辑了一个完整的课程,提出了所有建议,以避免混淆.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
AsyncTask<?, ?, ?> runningTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.button1);
// Because we implement OnClickListener, we only
// have to pass "this" (much easier)
btn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
// Detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
if (runningTask != null)
runningTask.cancel(true);
runningTask = new LongOperation();
runningTask.execute();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// Cancel running task(s) to avoid memory leaks
if (runningTask != null)
runningTask.cancel(true);
}
private final class LongOperation extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We were cancelled; stop sleeping!
}
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// You might want to change "executed" for the returned string
// passed into onPostExecute(), but that is up to you
}
}
}
Run Code Online (Sandbox Code Playgroud)
bbe*_*ard 73
我确定它正在正确执行,但你正在尝试更改后台线程中的UI元素,而这是不行的.
按如下方式修改您的调用和AsyncTask:
打电话给班级
注意:我个人建议onPostExecute()在执行AsyncTask线程的任何地方使用,而不是在扩展AsyncTask本身的类中使用.我认为它使代码更容易阅读,特别是如果您需要在多个地方处理结果略有不同的AsyncTask.
new LongThread() {
@Override public void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}.execute("");
Run Code Online (Sandbox Code Playgroud)
LongThread类(扩展AsyncTask):
@Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Executed";
}
Run Code Online (Sandbox Code Playgroud)
nit*_*esh 58
我已经创建了一个使用Android的AsyncTask的简单示例.它始于onPreExecute(), doInBackground(), publishProgress()最后onProgressUpdate().
在这个doInBackground()作为后台线程,而其他工作在UI线程.您无法访问doInBackground()中的UI元素.序列与我提到的相同.
但是,如果您需要更新任何窗口小部件,doInBackground您可以publishProgress从中doInBackground调用onProgressUpdate更新UI窗口小部件.
class TestAsync extends AsyncTask<Void, Integer, String> {
String TAG = getClass().getSimpleName();
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
for (int i=0; i<10; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";
}
protected void onProgressUpdate(Integer...a) {
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG + " onPostExecute", "" + result);
}
}
Run Code Online (Sandbox Code Playgroud)
在您的活动中将其称为:
new TestAsync().execute();
Run Code Online (Sandbox Code Playgroud)
Ted*_*opp 16
移动这两行:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
Run Code Online (Sandbox Code Playgroud)
超出你的AsyncTask的doInBackground方法,并将它们放在onPostExecute方法中.你AsyncTask应该看起来像这样:
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
Thread.sleep(5000); // no need for a loop
} catch (InterruptedException e) {
Log.e("LongOperation", "Interrupted", e);
return "Interrupted";
}
return "Executed";
}
@Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}
Run Code Online (Sandbox Code Playgroud)
TT-*_*T-- 14
AsyncTask允许您在后台线程上运行任务,同时将结果发布到UI线程.
用户应始终能够与应用程序进行交互,因此避免使用诸如从Web下载内容等任务阻止主(UI)线程非常重要 .
这就是我们使用的原因
AsyncTask.它通过包装UI线程消息队列和处理程序提供了一个简单的接口,允许您从其他线程发送和处理可运行的对象和消息.
AsyncTask是一个泛型类.(它在构造函数中采用参数化类型.)
它使用以下三种通用类型:
Params - 执行时发送给任务的参数类型.
Progress - 后台计算期间发布的进度单元的类型.
Result - 背景计算结果的类型.
并非所有类型都始终由异步任务使用.要将类型标记为未使用,只需使用类型Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
这三个参数对应于您可以覆盖的三个主要功能AsyncTask:
doInBackground(Params...)onProgressUpdate(Progress...)onPostExecute(Result)执行AsyncTask
execute()使用参数调用以发送到后台任务.
怎么了
在main/UI线程上,onPreExecute()被调用.(要在此线程中初始化某些内容,例如在用户界面上显示进度条.)
在后台线程上,doInBackground(Params...)被调用.(参数是传递给Execute函数的参数.)
长期任务应该发生的地方
必须覆盖至少Params使用AsyncTask.
execute在后台计算仍在执行时,调用以更新用户界面中的进度显示.(例如,为进度条设置动画或在文本字段中显示日志.)
doInBackground()被调用.在后台线程上,返回一个结果publishProgress(Progress...).这会触发下一步.
在main/UI线程上,onProgressUpdate()使用返回的结果调用.
再次使用阻止任务的示例是从Web下载内容,
该doInBackground()方法下载图像并将其存储在BitMap类型的对象中.该onPostExecute()方法获取位图并将其放在ImageView中.
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bitImage;
public DownloadImageTask(ImageView bitImage) {
this.bitImage = bitImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mBmp = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mBmp = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mBmp;
}
protected void onPostExecute(Bitmap result) {
bitImage.setImageBitmap(result);
}
}
Run Code Online (Sandbox Code Playgroud)
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Run Code Online (Sandbox Code Playgroud)
例B执行
new DownloadFilesTask().execute(url1, url2, url3);
Run Code Online (Sandbox Code Playgroud)
Gan*_*kar 11
执行异步任务时,任务将执行4个步骤:
下面是一个演示示例
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled())
break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你创建了,任务就会非常简单地执行:
new DownloadFilesTask().execute(url1, url2, url3);
Run Code Online (Sandbox Code Playgroud)
我希望这能帮到您...
Ode*_*ner 10
只是异步做某事的最简单的例子:
class MyAsyncTask extends android.os.AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
// Do something asynchronously
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
要运行它:
(new MyAsyncTask()).execute();
Run Code Online (Sandbox Code Playgroud)
别
如果您是AsyncTask的新手,那么在编写AsyncTask时会感到困惑.主要罪魁祸首是AsyncTask中使用的参数即AsyncTask<A, B, C>.基于方法的A,B,C(参数)签名不同,这使得事情更加混乱.
关键是不要记住.如果您可以想象您的任务真正需要做什么,那么在第一次尝试时使用正确的签名编写AsyncTask将是件小事.只需弄清楚你的输入,进度和输出是什么,你会很高兴.
AsyncTask是在后台线程中运行的后台任务.它需要一个输入,执行进度并给出输出.
即
Input.
之间
Progress和Output
Input和ProgressonProgressUpdate()`也有关系
如何在代码中写出来?
DownloadTask extends AsyncTask<String, Integer, String>{
// Always same signature
@Override
public void onPreExecute()
{}
@Override
public String doInbackGround(String... parameters)
{
// Download code
int downloadPerc = // Calculate that
publish(downloadPerc);
return "Download Success";
}
@Override
public void onPostExecute(String result)
{
super.onPostExecute(result);
}
@Override
public void onProgressUpdate(Integer... parameters)
{
// Show in spinner, and access UI elements
}
}
Run Code Online (Sandbox Code Playgroud)
你将如何运行这个任务?
new DownLoadTask().execute("Paradise.mp3");
Run Code Online (Sandbox Code Playgroud)
小智 6
当您在工作线程中时,您无法直接操作Android上的UI元素.
当您使用AsyncTask时,请了解回调方法.
例如:
public class MyAyncTask extends AsyncTask<Void, Void, Void>{
@Override
protected void onPreExecute() {
// Here you can show progress bar or something on the similar lines.
// Since you are in a UI thread here.
super.onPreExecute();
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// After completing execution of given task, control will return here.
// Hence if you want to populate UI elements with fetched data, do it here.
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// You can track you progress update here
}
@Override
protected Void doInBackground(Void... params) {
// Here you are in the worker thread and you are not allowed to access UI thread from here.
// Here you can perform network operations or any heavy operations you want.
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
仅供参考:要从工作线程访问UI线程,可以在视图上使用runOnUiThread()方法或post方法.
例如:
runOnUiThread(new Runnable() {
textView.setText("something.");
});
or
yourview.post(new Runnable() {
yourview.setText("something");
});
Run Code Online (Sandbox Code Playgroud)
这将有助于您更好地了解事情.因此,在您的情况下,您需要在onPostExecute()方法中设置textview.
我建议通过使用此库进行背景工作来使您的生活更轻松:
https://github.com/Arasthel/AsyncJobLibrary
就这么简单...
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
@Override
public void doOnBackground() {
startRecording();
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
927989 次 |
| 最近记录: |