方法必须从主线程调用,当前推断线程是worker
Method must be called from main thread,currenty inferred thread is worker
我正在尝试每 15 分钟或类似的时间更换一次 Android 的墙纸。用户可以选择时间,我是 运行 使用 Workmanager 的周期性工作。
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(SomeWorker.class, 15, TimeUnit.MINUTES).build();
WorkManager.getInstance().enqueue(periodicWorkRequest);
我这样称呼我的工人Class。工作class是这个
public class SomeWorker extends Worker {
Context context = getApplicationContext();
private String URL;
@NonNull
@Override
public Result doWork() {
new FetchWallpaper().execute();
return Result.SUCCESS;
}
private class FetchWallpaper extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... voids) {
try
{
URL = "myurl.com";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Response responses = null;
try {
responses = client
.newCall(request)
.execute();
String jsonData = responses.body().string();
JSONArray jsonArr = new JSONArray(jsonData);
JSONObject c = jsonArr.getJSONObject(new Random().nextInt(jsonArr.length()));
String imageUrl = c.getString("wallpaper");
Bitmap result= Picasso.with(getApplicationContext())
.load(imageUrl)
.get();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(result);
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
Date currentTime = Calendar.getInstance().getTime();
}
catch (Exception e)
{
Date currentTime = Calendar.getInstance().getTime();
}
return null;
}
}}
在那条特定的线上,
new FetchWallpaper().execute();
我收到错误消息说它必须从主线程调用。我是 Android 的新手,我不知道这是否是个好方法。
如果有更好的方法来执行此类任务,请告诉我。
您无法从 doInBackground
方法更新 UI。如果你想在 UI 上做某事,你必须在 UI 主线程上做。因此,在 onPostExecute
方法中将 setBitmap
代码编写为 onPostExecute
在主 UI 线程上。
为此,将 AsyncTask 的第三个参数设置为 String
AsyncTask<Void, Void, String>
因此 return 类型的 doInBackground
方法将是 String
protected String doInBackground(Void... voids)
...
...
return imageUrl;
}
你的 onPostExecute 方法就像
@Override
protected void onPostExecute(String imageUrl) {
super.onPostExecute(imageUrl);
Bitmap result= Picasso.with(getApplicationContext())
.load(imageUrl)
.get();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(result);
} catch (Exception ex) {
ex.printStackTrace();
}
}
Worker
class 已经在后台线程上调用了 doWork
- 您根本不需要使用 AsyncTask
。
只需将所有内容从您的 doInBackground
方法直接移至 Worker 的 doWork
。
new AsyncTask<Void, Bitmap, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = null;
try {
InputStream inputStream;
inputStream = new java.net.URL(url).openStream();
bitmap = BitmapFactory.decodeStream(inputStream);
}catch (Exception e) {
logAppE(TAG, "BITMAP ERROR -> " + e.getMessage());
}
return bitmap
}
@Override
protected void onPostExecute(Bitmap s) {
try {
Glide.with(context).asGif().load(s).into(imgViewGIF);
} catch (Exception e) {
logAppE(TAG, "BITMAP -> " + e.getMessage());
}
}
}.execute();
我正在尝试每 15 分钟或类似的时间更换一次 Android 的墙纸。用户可以选择时间,我是 运行 使用 Workmanager 的周期性工作。
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(SomeWorker.class, 15, TimeUnit.MINUTES).build();
WorkManager.getInstance().enqueue(periodicWorkRequest);
我这样称呼我的工人Class。工作class是这个
public class SomeWorker extends Worker {
Context context = getApplicationContext();
private String URL;
@NonNull
@Override
public Result doWork() {
new FetchWallpaper().execute();
return Result.SUCCESS;
}
private class FetchWallpaper extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... voids) {
try
{
URL = "myurl.com";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Response responses = null;
try {
responses = client
.newCall(request)
.execute();
String jsonData = responses.body().string();
JSONArray jsonArr = new JSONArray(jsonData);
JSONObject c = jsonArr.getJSONObject(new Random().nextInt(jsonArr.length()));
String imageUrl = c.getString("wallpaper");
Bitmap result= Picasso.with(getApplicationContext())
.load(imageUrl)
.get();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(result);
} catch (Exception ex) {
ex.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
Date currentTime = Calendar.getInstance().getTime();
}
catch (Exception e)
{
Date currentTime = Calendar.getInstance().getTime();
}
return null;
}
}}
在那条特定的线上,
new FetchWallpaper().execute();
我收到错误消息说它必须从主线程调用。我是 Android 的新手,我不知道这是否是个好方法。 如果有更好的方法来执行此类任务,请告诉我。
您无法从 doInBackground
方法更新 UI。如果你想在 UI 上做某事,你必须在 UI 主线程上做。因此,在 onPostExecute
方法中将 setBitmap
代码编写为 onPostExecute
在主 UI 线程上。
为此,将 AsyncTask 的第三个参数设置为 String
AsyncTask<Void, Void, String>
因此 return 类型的 doInBackground
方法将是 String
protected String doInBackground(Void... voids)
...
...
return imageUrl;
}
你的 onPostExecute 方法就像
@Override
protected void onPostExecute(String imageUrl) {
super.onPostExecute(imageUrl);
Bitmap result= Picasso.with(getApplicationContext())
.load(imageUrl)
.get();
WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
try {
wallpaperManager.setBitmap(result);
} catch (Exception ex) {
ex.printStackTrace();
}
}
Worker
class 已经在后台线程上调用了 doWork
- 您根本不需要使用 AsyncTask
。
只需将所有内容从您的 doInBackground
方法直接移至 Worker 的 doWork
。
new AsyncTask<Void, Bitmap, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = null;
try {
InputStream inputStream;
inputStream = new java.net.URL(url).openStream();
bitmap = BitmapFactory.decodeStream(inputStream);
}catch (Exception e) {
logAppE(TAG, "BITMAP ERROR -> " + e.getMessage());
}
return bitmap
}
@Override
protected void onPostExecute(Bitmap s) {
try {
Glide.with(context).asGif().load(s).into(imgViewGIF);
} catch (Exception e) {
logAppE(TAG, "BITMAP -> " + e.getMessage());
}
}
}.execute();