Android 方法必须从主线程调用,当前推断的线程是辅助线程
我正在尝试每隔15分钟或类似的时间更换一次Android的壁纸。用户可以选择时间,我正在使用Workmanager运行定期工作Android 方法必须从主线程调用,当前推断的线程是辅助线程,android,android-architecture-components,android-jetpack,android-workmanager,Android,Android Architecture Components,Android Jetpack,Android Workmanager,我正在尝试每隔15分钟或类似的时间更换一次Android的壁纸。用户可以选择时间,我正在使用Workmanager运行定期工作 PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(SomeWorker.class, 15, TimeUnit.MINUTES).build(); WorkManager.getInstance().enqueue(periodicWorkRequest); 这样我就叫我
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(SomeWorker.class, 15, TimeUnit.MINUTES).build();
WorkManager.getInstance().enqueue(periodicWorkRequest);
这样我就叫我的工人阶级。工人阶级就是这样
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;
}
}}
我得到的错误是它必须从主线程调用。我是Android新手,我不知道这是否是个好方法。
请告诉我是否有更好的方法来执行此类任务。您不能通过
doInBackground
方法更新UI。若你们想在UI上做些什么,你们必须在主UI线程上做。因此,将onPostExecute
方法中的setBitmap
代码作为主UI线程上的onPostExecute
编写
为此,将AsyncTask的第三个参数设置为String
AsyncTask<Void, Void, 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
类已经在后台线程上调用了doWork
——您根本不需要使用AsyncTask
只需将您的
doInBackground
方法中的所有内容直接移动到工作人员的doWork
我尝试了此解决方案,但只要应用程序正在运行,它就会更改墙纸,只要我关闭应用程序,工作经理就会工作,但不会更新墙纸。这与此问题无关。这个答案与停止抛出异常有关。为此,你们可以问另一个问题。若这个答案有助于你们解决异常,那个么你们可以接受它作为书面答案。
@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();
}
}