我创建了一个新闻小部件。它从服务器获取JSON然后解析它并将其显示给用户。但是在开始时我得到一个错误,见下文。我也试过没有服务,只有AsyncTask
,我仍然有错误:
Can't create handler inside thread that has not called Looper.prepare()
我该怎么办?
public class Widget extends AppWidgetProvider {
private RemoteViews update;
private ArrayList<String> title = new ArrayList<String>();
private ArrayList<String> images = new ArrayList<String>();
private ArrayList<String> url = new ArrayList<String>();
private ArrayList<Integer> timestamp = new ArrayList<Integer>();
private Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
ComponentName thisWidget = new ComponentName(context, GetNews.class);
int[] appWidgetId = appWidgetManager.getAppWidgetIds(thisWidget);
Intent intent = new Intent(context.getApplicationContext(), GetNews.class);
intent.putExtra("appWidgetIds", appWidgetIds);
context.startService(intent);
}
public String getTime(String time, Context context){
long jsonTimestamp = Long.parseLong(time);
TimeZone timeZone = TimeZone.getDefault();
Locale locale = Locale.getDefault();
Calendar calendar = Calendar.getInstance(timeZone, locale);
calendar.setTimeInMillis(jsonTimestamp * 1000);
CharSequence date = DateUtils.getRelativeDateTimeString(context, System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE,0);
final long diff = System.currentTimeMillis() - calendar.getTimeInMillis();
final int MINUTE_MILLIS = 1000*60;
final int HOUR_MILLIS = 1000*60*60;
final int DAY_MILLIS = 1000*60*60*24;
if(diff < 24*HOUR_MILLIS){
SimpleDateFormat s = new SimpleDateFormat("HH:mm");
String format = s.format(new Date(calendar.getTimeInMillis()));
return format+"";
}
else {
return date+"";
}
}
public static boolean isConnected(Context context)
{
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo().isConnectedOrConnecting();
}
public void WidgetUpdate(Context context){
}
class LoadBitmap extends AsyncTask<Void, Void, Bitmap>{
String Url = "http://www.gazeta.uz/i/gazetauz-logo-120.gif";
public void loadImage(String url){
if(url != null){
this.Url = url;
}
}
@Override
protected Bitmap doInBackground(Void... params) {
InputStream ips = null;
try {
ips = new URL(Url).openConnection().getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(ips);
return bitmap;
}
}
class LoadNews extends AsyncTask<Void, Void, JSONObject> {
@Override
protected JSONObject doInBackground(Void... params) {
InputStream ips = null;
String jstring = null;
JSONObject json = null;
try {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("mysite");
HttpResponse response = client.execute(get);
ips = response.getEntity().getContent();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader buffer = new BufferedReader(new InputStreamReader(ips, "UTF-8"));
StringBuilder str = new StringBuilder();
String line;
while((line = buffer.readLine()) != null){
str.append(line);
}
ips.close();
jstring = str.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
try {
json = new JSONObject(jstring);
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
@Override
protected void onPostExecute(JSONObject result){
super.onPostExecute(result);
}
}
public class GetNews extends Service {
@Override
public void onStart(Intent intent, int startId){
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getBaseContext());
RemoteViews update = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget_main);
Context context = getBaseContext();
int[] appWidgetIds = intent.getIntArrayExtra("appWidgetIds");
ComponentName thisWidget = new ComponentName(getBaseContext(), Widget.class);
int[] appWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
for(int appWidgets : appWidgetIds){
LoadNews news = new LoadNews();
news.execute();
try {
JSONObject result = news.get();
if(result != null){
JSONArray jarray = result.optJSONArray("data");
title.clear();
images.clear();
url.clear();
for(int i = 0; i < jarray.length(); i++){
JSONObject jrss = jarray.optJSONObject(i);
title.add(jrss.optString("title"));
images.add(jrss.optString("img"));
url.add(jrss.optString("url"));
timestamp.add(jrss.optInt("publish_timestamp"));
}
update.setTextViewText(R.id.text, title.get(0).substring(0, 65)+"...");
update.setTextViewText(R.id.text2,title.get(1).substring(0, 65)+"...");
update.setTextViewText(R.id.text3, title.get(2).substring(0, 65)+"...");
update.setTextViewText(R.id.text4, title.get(3).substring(0, 65)+"...");
update.setTextViewText(R.id.text_1, getTime(timestamp.get(0) + "", context));
update.setTextViewText(R.id.text_2, getTime(timestamp.get(1) + "", context));
update.setTextViewText(R.id.text_3, getTime(timestamp.get(2) + "", context));
update.setTextViewText(R.id.text_4, getTime(timestamp.get(3)+"",context));
update.setOnClickPendingIntent(R.id.text, PendingIntent.getActivity(context, 0, new Intent(Intent.ACTION_VIEW, Uri.parse(url.get(0))), 0));
update.setOnClickPendingIntent(R.id.text2, PendingIntent.getActivity(context, 0, new Intent(Intent.ACTION_VIEW, Uri.parse(url.get(1))), 0));
LoadBitmap bitmap = new LoadBitmap();
bitmap.loadImage(images.get(0));
bitmap.execute();
update.setImageViewBitmap(R.id.imageView, bitmap.get());
LoadBitmap bitmap2 = new LoadBitmap();
bitmap2.loadImage(images.get(1));
bitmap2.execute();
update.setImageViewBitmap(R.id.imageView2, bitmap2.get());
LoadBitmap bitmap3 = new LoadBitmap();
bitmap3.loadImage(images.get(2));
bitmap3.execute();
update.setImageViewBitmap(R.id.imageView3, bitmap3.get());
LoadBitmap bitmap4 = new LoadBitmap();
bitmap4.loadImage(images.get(3));
bitmap4.execute();
update.setImageViewBitmap(R.id.imageView4, bitmap4.get());
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
appWidgetManager.updateAppWidget(startId, update);
}
stopSelf();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
}
logcat的
ERROR/AndroidRuntime(2765): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate service com.afishamedia.widget.Widget$GetNews: java.lang.InstantiationException: can't instantiate class com.afishamedia.widget.Widget$GetNews; no empty constructor
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2637)
at android.app.ActivityThread.access$1600(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1326)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5191)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.InstantiationException: can't instantiate class com.afishamedia.widget.Widget$GetNews; no empty constructor
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2634)
... 10 more