我试图搜索有关StackView Widget的信息,发现了很多东西,但是没有人曾经从url获取数据。
所以问题是,当我处理url时,我的RemoteViews为null,因此它们什么也不显示。完成该过程后,我想从asyntask更新RemoteViews(位于同一类中)。我怎样才能做到这一点 ?还是同步它们?
这是我的Widget服务代码:
public class RSSService extends RemoteViewsService {
private ManagerRSS mr;
private Cursor c;
private int lenght;
private List<Provider> mWidgetItems = new ArrayList<Provider>();
private RemoteViews rv = null;
public ArrayList<Item> result = new ArrayList<Item>();
private boolean isFinished = false;
@Override
public void onCreate() {
// TODO Auto-generated method stub
mr = new ManagerRSS(this.getApplicationContext());
mr.open();
mr.openRead();
c = mr.getCursor();
lenght = c.getCount();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
c.close();
mr.close();
super.onDestroy();
}
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
// TODO Auto-generated method stub
return new RSSRemoteViewsFactory(this.getApplicationContext(), intent);
}
class RSSRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory{
private Context mContext;
private int mAppWidgetId;
public RSSRemoteViewsFactory(Context applicationContext, Intent intent) {
// TODO Auto-generated constructor stub
mContext = applicationContext;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return lenght;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public RemoteViews getLoadingView() {
// TODO Auto-generated method stub
return null;
}
@Override
public RemoteViews getViewAt(int position) {
if(isFinished){
rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).getTitle());
if(mWidgetItems.get(position).getTitle().equals("El Pais")){
rv.setImageViewResource(R.id.iNotice, R.drawable.elpais);
}else if(mWidgetItems.get(position).getTitle().equals("Marca")){
rv.setImageViewResource(R.id.iNotice, R.drawable.marca);
}else if(mWidgetItems.get(position).getTitle().equals("As")){
rv.setImageViewResource(R.id.iNotice, R.drawable.as1);
}else if(mWidgetItems.get(position).getTitle().equals("Ideal")){
rv.setImageViewResource(R.id.iNotice, R.drawable.ideal);
}else{
rv.setImageViewResource(0, R.drawable.undefined);
}
rv.setTextViewText(R.id.tvLastNotice, result.get(position).getTitle());
rv.setTextViewText(R.id.tvLastNoticePublish, result.get(position).getPubDate());
Bundle extras = new Bundle();
extras.putString(Widget.NAME_DIARY, mWidgetItems.get(position).getTitle());
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
try {
System.out.println("Loading view " + position);
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return rv;
}else{
return null;
}
}
@Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return 1;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
@Override
public void onCreate() {
while(c.moveToNext()){
String title = c.getString(c.getColumnIndex(Contrato.TableRSS.TITLE));
String link = c.getString(c.getColumnIndex(Contrato.TableRSS.LINK));
long _id = c.getLong(c.getColumnIndex(Contrato.TableRSS._ID));
mWidgetItems.add(new Provider(_id, title, link));
executeThread(link, c.getPosition());
}
}
void executeThread(String type_link,int position){
myThread exe = new myThread();
exe.setOnlyFirst(true);
exe.execute(new String[]{type_link});
}
private class myThread extends MyAsyncTask{
@Override
protected void onPostExecute(ArrayList<Item> result2) {
// TODO Auto-generated method stub
super.onPostExecute(result2);
for(int i=0;i<result2.size();i++) result.add(result2.get(i));
if(result.size()+1 == c.getCount()) isFinished = true;
}
}
@Override
public void onDataSetChanged() {
}
@Override
public void onDestroy() {mWidgetItems.clear();}
}
}
这是我的WidgetProvider:
public class Widget extends AppWidgetProvider{
public static final String ON_TOUCH = "com.cool.nightrss.ON_TOUCH";
public static final String ID_DIARY = "com.cool.nightrss.ID_DIARY";
public static final String ID_NOTICE = "com.cool.nightrss.ID_NOTICE";
public static final String NAME_DIARY = "com.cool.nightrss.NAME_DIARY";
public static final String LINK_NOTICE = "com.cool.nightrss.LINK_NOTICE";
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals(ON_TOUCH)) {
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
String name = intent.getStringExtra(NAME_DIARY);
Toast.makeText(context, "Touched view " + name +" ID "+appWidgetId, Toast.LENGTH_SHORT).show();
}
super.onReceive(context, intent);
}
@SuppressWarnings("deprecation")
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
for (int i = 0; i < appWidgetIds.length; ++i) {
Intent intent = new Intent(context, RSSService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
Intent toastIntent = new Intent(context, Widget.class);
toastIntent.setAction(Widget.ON_TOUCH);
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}
最佳答案
您可以在类RSSRemoteViewsFactory中使用onDataSetChanged方法。当您在与此工厂相对应的集合视图上调用AppWidgetManager notifyAppWidgetViewDataChanged时,将触发此事件。您可以同步在这里进行举升。例如,如果您需要处理图像,从网络中获取内容等,则可以在此处同步进行。在这里完成工作时,小部件将保持其当前状态,因此您不必担心锁定小部件。
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private final String TAG = StackRemoteViewsFactory.class.getSimpleName();
private Context mContext;
private int mAppWidgetId;
private List<Game> mGameItems = new ArrayList<Game>();
public StackRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
public void onCreate() {
}
public void onDestroy() {
mGameItems.clear();
}
public int getCount() {
return mGameItems.size();
}
public RemoteViews getViewAt(int position) {
Game game = mGameItems.get(position);
Bundle extras = new Bundle();
extras.putString(StackWidgetProvider.EXTRA_ITEM, game.getGameUrl());
Intent fillInIntent = new Intent();
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
Bitmap bitmap = null;
try {
URL imageUrl = new URL(game.getImageUrl());
bitmap = BitmapFactory.decodeStream(imageUrl.openConnection().getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
rv.setImageViewBitmap(R.id.widget_item, bitmap);
return rv;
}
public RemoteViews getLoadingView() {
return null;
}
public int getViewTypeCount() {
return 1;
}
public long getItemId(int position) {
return position;
}
public boolean hasStableIds() {
return true;
}
public void onDataSetChanged() {
final String uri = <set your url>
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(uri);
String jsonData = null;
/**
* Fetch JSON from web service
* TODO: try to call a AsyncTask
*/
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream inputStream = httpEntity.getContent();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder data = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
data.append(line);
}
jsonData = new String(data);
Log.d(TAG, String.format("JSON: %s", jsonData));
} catch (IOException e) {
e.printStackTrace();
}
/**
* Mapping JSON String to objects
* TODO: Probably move the code to a dedicated class and use GSON to do the mapping?????
*/
if(jsonData != null && !jsonData.equals("")) {
try {
JSONArray jsonArray = new JSONArray(jsonData);
for(int index = 0; index < jsonArray.length(); index++) {
JSONObject jsonObject = jsonArray.getJSONObject(index);
String id = jsonObject.getString("id");
String imageUrl = jsonObject.getString("imageUrl");
String gameUrl = jsonObject.getString("gameUrl");
mGameItems.add(
new Game(id, imageUrl, gameUrl)
);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.d(TAG, String.format("List of games: %s", mGameItems));
}
}
在以下示例中,我从网络服务器中获取json,然后从每个项目中获取图像。 onDataSetChanged用于获取json内容,而在getViewAt中则获取图像。
在Google提供的StackView示例中查看评论-
http://docs.huihoo.com/android/3.0/resources/samples/StackWidget/index.html
希望对您有帮助
关于android - AsyncTask与Stack View小部件中的RemoteViews,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21614460/