【问题标题】:Android Widget with ListView populated from AsyncTask从 AsyncTask 填充 ListView 的 Android 小部件
【发布时间】:2018-03-25 22:34:28
【问题描述】:

我正在为我的应用程序创建一个小部件,但是当我必须填充列表视图时我被卡住了。我使用我在 WidgetDataProvider(实现 RemoteViewsService.RemoteViewsFactory)的 onCreate() 中调用的 asynctask 从我的 web db 中获取每个项目。 问题是,通常当我创建小部件时,它不会填充列表,我必须等待几秒钟才能在主屏幕中释放小部件。

如果我抓住并释放小部件,它会如下所示:empty widget

如果我等待,它会像这样显示:right widget

这是我的代码:

AppWidget

public class AppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget);

    Intent intent = new Intent(context, LoginActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    views.setOnClickPendingIntent(R.id.widget_title, pendingIntent);

    views.setRemoteAdapter(R.id.widget_listView, new Intent(context, WidgetService.class));
    appWidgetManager.updateAppWidget(appWidgetId, views);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    super.onUpdate(context, appWidgetManager, appWidgetIds);
    for (int appWidgetId : appWidgetIds) {
        updateAppWidget(context, appWidgetManager, appWidgetId);
    }
}

@Override
public void onEnabled(Context context) {
}

@Override
public void onDisabled(Context context) {
}

}

**WidgetService **

public class WidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
    return new WidgetDataRemote(this, intent);
}}

WidgetDataRemote

public class WidgetDataRemoteimplements RemoteViewsService.RemoteViewsFactory {
Context context;
Intent intent;
ArrayList<String> date = new ArrayList<>();
ArrayList<String> subj = new ArrayList<>();
ArrayList<String> type = new ArrayList<>();
ArrayList<String> comment = new ArrayList<>();
JSONParser jsonParser = new JSONParser();
ArrayList<String> subjFromDb = new ArrayList<>();
int pippo = 0;

public WidgetDataRemote(Context context, Intent intent) {
    this.context = context;
    this.intent = intent;
}

@Override
public RemoteViews getViewAt(int position) {
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.item_widget);
    remoteViews.setTextViewText(R.id.task_data, date.get(position));
    remoteViews.setTextViewText(R.id.task_subject, subj.get(position));
    remoteViews.setTextViewText(R.id.task_type, type.get(position));
    remoteViews.setTextViewText(R.id.task_comment, comment.get(position));
    return remoteViews;
}

@Override
public void onCreate() {
    new LoadSubjects().execute();
}

@Override
public void onDataSetChanged() {
}

@Override
public void onDestroy() {
    date.clear();
    subj.clear();
    type.clear();
    comment.clear();
}

@Override
public int getCount() {
    return date.size();
}

@Override
public RemoteViews getLoadingView() {
    return null;
}

@Override
public int getViewTypeCount() {
    return 1;
}

@Override
public long getItemId(int id) {
    return id;
}

@Override
public boolean hasStableIds() {
    return true;
}

class LoadSubjects extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        subjFromDb.clear();
        pippo = 0;
    }

    @Override
    protected String doInBackground(String... args) {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("class", User.getClasse()));
        JSONArray json = jsonParser.makeHttpRequestArray(Constants.URL_LOAD_SUBJECTS, "POST", params);
        try {
            if (!json.toString().equals("[null]")) {
                for (int i = 0; i < json.length(); i++) {
                    JSONObject c = json.getJSONObject(i);
                    String subj = c.getString(Constants.TAG_NAME);
                    subjFromDb.add(subj);
                }
            } else {
                pippo = 1;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(String file_url) {
        if (pippo == 0) {
            new LoadTasks().execute();
        }
    }

    class LoadTasks extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pippo = 0;
        }

        @Override
        protected String doInBackground(String... args) {
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("id_class", User.getClasse()));
            JSONArray json = jsonParser.makeHttpRequestArray(Constants.URL_LOAD_TASKS, "POST", params);
            try {
                if (!json.toString().equals("[null]")) {
                    for (int i = 0; i < json.length(); i++) {
                        JSONObject c = json.getJSONObject(i);
                        Date data = null;
                        try {
                            data = new SimpleDateFormat("yyyy-MM-dd").parse(c.getString(Constants.TAG_DATE));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        String newDate = new SimpleDateFormat("dd/MM/yyyy").format(data);
                        if (subjFromDb.contains(c.getString(Constants.TAG_SUBJECT))) {
                            date.add(newDate);
                            subj.add(c.getString(Constants.TAG_SUBJECT));
                            type.add(c.getString(Constants.TAG_TYPE));
                            comment.add(c.getString(Constants.TAG_COMMENT));
                        }
                    }
                } else {
                    pippo = 1;
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(String file_url) {
            if (pippo == 0){
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                ComponentName thisWidget = new ComponentName(context, WidgetDataProvider.class);
                int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
                appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listView);
                // I use this to update the listview after fetch data. Is it correct?
            }
        }
    }
}}

【问题讨论】:

    标签: android listview android-asynctask widget


    【解决方案1】:

    我仅使用 TimerTask 并在 onPostExecute 中修改更新过程就解决了我的问题。这是我更改的文件:

    WidgetDataRemote

    public class WidgetDataRemote implements RemoteViewsService.RemoteViewsFactory {
    final Context context;
    Intent intent;
    ArrayList<String> date = new ArrayList<>();
    ArrayList<String> subj = new ArrayList<>();
    ArrayList<String> type = new ArrayList<>();
    ArrayList<String> comment = new ArrayList<>();
    JSONParser jsonParser = new JSONParser();
    ArrayList<String> subjFromDb = new ArrayList<>();
    final Context sad;
    int pippo = 0;
    
    public WidgetDataRemote(Context context, Intent intent) {
        this.context = context;
        this.intent = intent;
        sad = context;
        final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            new LoadSubjects().execute();
                        } catch (Exception ignored) {}
                    }
                });
            }
        };
        timer.schedule(doAsynchronousTask, 0, 60000);
    }
    
    @Override
    public RemoteViews getViewAt(int position) {
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.item_widget);
        if(date.size()>0) {
            remoteViews.setTextViewText(R.id.task_data, date.get(position));
            remoteViews.setTextViewText(R.id.task_subject, subj.get(position));
            remoteViews.setTextViewText(R.id.task_type, type.get(position));
            remoteViews.setTextViewText(R.id.task_comment, comment.get(position));
        }else{
            remoteViews.setTextViewText(R.id.task_data, "");
            remoteViews.setTextViewText(R.id.task_subject, "loading");
            remoteViews.setTextViewText(R.id.task_type, "");
            remoteViews.setTextViewText(R.id.task_comment, "");
        }
        return remoteViews;
    }
    
    @Override
    public void onCreate() {
        Toast.makeText(context, "Loading...", Toast.LENGTH_LONG).show();
    }
    
    @Override
    public void onDataSetChanged() {
    }
    
    @Override
    public void onDestroy() {
        date.clear();
        subj.clear();
        type.clear();
        comment.clear();
    }
    
    @Override
    public int getCount() {
        return date.size();
    }
    
    @Override
    public RemoteViews getLoadingView() {
        return null;
    }
    
    @Override
    public int getViewTypeCount() {
        return 1;
    }
    
    @Override
    public long getItemId(int id) {
        return id;
    }
    
    @Override
    public boolean hasStableIds() {
        return true;
    }
    
    class LoadSubjects extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            subjFromDb.clear();
            pippo = 0;
        }
    
        @Override
        protected String doInBackground(String... args) {
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("class", User.getClasse()));
            JSONArray json = jsonParser.makeHttpRequestArray(Constants.URL_LOAD_SUBJECTS, "POST", params);
            try {
                if (!json.toString().equals("[null]")) {
                    for (int i = 0; i < json.length(); i++) {
                        JSONObject c = json.getJSONObject(i);
                        String subj = c.getString(Constants.TAG_NAME);
                        subjFromDb.add(subj);
                    }
                } else {
                    pippo = 1;
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        protected void onPostExecute(String file_url) {
            if (pippo == 0) {
                new LoadTasks().execute();
            }
        }
    }
    
    class LoadTasks extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            date.clear();
            subj.clear();
            type.clear();
            comment.clear();
            pippo = 0;
        }
    
        @Override
        protected String doInBackground(String... args) {
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("id_class", User.getClasse()));
            JSONArray json = jsonParser.makeHttpRequestArray(Constants.URL_LOAD_TASKS, "POST", params);
            try {
                if (!json.toString().equals("[null]")) {
                    for (int i = 0; i < json.length(); i++) {
                        JSONObject c = json.getJSONObject(i);
                        Date data = null;
                        try {
                            data = new SimpleDateFormat("yyyy-MM-dd").parse(c.getString(Constants.TAG_DATE));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        String newDate = new SimpleDateFormat("dd/MM/yyyy").format(data);
                        if (subjFromDb.contains(c.getString(Constants.TAG_SUBJECT))) {
                            date.add(newDate);
                            subj.add(c.getString(Constants.TAG_SUBJECT));
                            type.add(c.getString(Constants.TAG_TYPE));
                            comment.add(c.getString(Constants.TAG_COMMENT));
                        }
                    }
                } else {
                    pippo = 1;
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        protected void onPostExecute(String file_url) {
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(sad);
            appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetManager.getAppWidgetIds(new ComponentName(sad, AppWidget.class)), R.id.widget_listView);
        }
    }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      相关资源
      最近更新 更多