Android 方法必须从主线程调用,当前推断的线程是辅助线程

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); 这样我就叫我

我正在尝试每隔15分钟或类似的时间更换一次Android的壁纸。用户可以选择时间,我正在使用Workmanager运行定期工作

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();
      }

}