问题
I have an appwidget that can download some data from a web service (in a thread in onReceive()
) by clicking on it. After that is finished the GUI of the widget gets updated in updateWidget(...)
(= re-drawn).
I want to make a toast when this is done. I tried a lot like to make a toast at the end of updateWidget(...)
by passing the context from the thread to the toast, but that didn't work. The problem seems to be the context. Because my class inherits from AppWidgetProvider
and NOT from Activity I CANNOT use stuff like getApplicationContext()
. I guess I just need to get the right context for the toast, but I have no idea how to do that.
Here is the relevant code:
@Override
public void onReceive(Context context, Intent intent)
{
// Name of the action of the intent
final String action = intent.getAction();
// This way the context and the intent can be used in the thread
final Context ctx = context;
final Intent i = intent;
if (action.equals(COUNT_DOWN) == true || action.equals(COUNT_UP) == true)
{
// Show toast to inform the user that this feature is only available in the full version
Toast.makeText(context, R.string.no_groupchange, Toast.LENGTH_SHORT).show();
}
// Update current group
else if (action.equals(UPDATE_WIDGET))
{
// Check for internet connection
if (isOnline(context) == true)
{
// Show toast to inform the user that refreshing the data has started
Toast.makeText(context, R.string.refreshing, Toast.LENGTH_SHORT).show();
// This way the complete internet communication is independent from the GUI
// Also works at low speed internet connection
Thread myThread = new Thread(new Runnable()
{
@Override
public void run()
{
// TODO Auto-generated method stub
int currentGroupOrderID = soapManager.getCurrentGroupOrderID(LEAGUE_SC);
theGroup = soapManager.getGroup(currentGroupOrderID, LEAGUE_SC, SAISON);
nextMatch = soapManager.getNextMatch(LEAGUE_SC);
updateWidget(ctx, i);
}
});
myThread.start();
}
else
{
Toast.makeText(context, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
}
super.onReceive(context, intent);
}
public void updateWidget(Context context, Intent intent)
{
// Creating remoteViews for updating the widget
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout_simple);
// Fill the textViews with text
setTextViewsFromTheGroup(remoteViews);
setNextMatchTextView(remoteViews);
// Update the widget
ComponentName widget = new ComponentName(context, SoccerWidgetProvider.class);
AppWidgetManager awm = AppWidgetManager.getInstance(context);
awm.updateAppWidget(widget, remoteViews);
// This way the widget doesn't stop reacting after some time
final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)
{
attachIntents(context, remoteViews, appWidgetId);
}
// HERE I WANT TO MAKE A TOAST!!!
}
回答1:
You need to call Toast.makeText
from the UI thread. You can do that by doing:
runOnUiThread(new Runnable() {
public void run()
{
Toast.makeText(context, R.string.refreshing, Toast.LENGTH_SHORT).show();
}
});
来源:https://stackoverflow.com/questions/9757730/cant-make-a-toast-from-thread-in-an-appwidgetprovider-class