必须从主线程调用方法,当前推断的线程为worker

时间:2018-08-12 06:05:14

标签: 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);

这样,我称呼我的工人阶级。工人阶级是这个

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新手,不知道这是否是好方法。 请让我知道是否有更好的方法来执行此类任务。

2 个答案:

答案 0 :(得分:3)

Worker类已经在后台线程上调用了doWork-您根本不需要使用AsyncTask

只需将您的doInBackground方法中的所有内容直接移到Worker的doWork中即可。

答案 1 :(得分:0)

您无法通过doInBackground方法更新UI。如果要在UI上执行某些操作,则必须在Main UI线程上执行该操作。因此,请在setBitmap方法中以onPostExecute的形式在主UI线程上编写onPostExecute代码。

为此,请将AsyncTask的第三个参数设置为String

AsyncTask<Void, Void, String>

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

}