我正在尝试执行一个相对简单的任务:我有一个片段启动服务从远程服务器中提取一些JSON.然后,我想使用广播将该JSON传递回原始调用片段,并将BroadcastReceiver定义为片段中的匿名类.
但是,每当我尝试这样做时,我都会收到以下错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.roundarch.codetest, PID: 21974
android.app.RemoteServiceException: can't deliver broadcast
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
码:
public class Part3Fragment extends Fragment {
PostCodeAdapter postCodeAdapter;
ListView listView;
BroadcastReceiver receiver;
IntentFilter intentFilter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_part3, null);
initialiseReceiver();
View emptyView = (View) view.findViewById(R.id.empty_textview);
ListView listView = (ListView) view.findViewById(R.id.part3_listview);
listView.setEmptyView(emptyView);
// TODO - the listview will need to be provided with a source for data
// TODO - (optional) you can set up handling to list item selection if you wish
return view;
}
@Override
public void onResume() {
super.onResume();
initialiseReceiver();
getActivity().startService(new Intent(getActivity(), Part3Service.class));
}
public void initialiseReceiver(){
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getBundleExtra("bundle");
ArrayList postcodes = (ArrayList) bundle.getSerializable("postcodeArray");
updatePostcodes(postcodes);
}
};
intentFilter = new IntentFilter("JSON_RECEIVED");
getActivity().registerReceiver(receiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
}
private void updatePostcodes(ArrayList postcodes) {
if (postcodes.size() > 0){
postCodeAdapter = new PostCodeAdapter(getActivity(), R.layout.part3_listview_item, postcodes);
listView.setAdapter(postCodeAdapter);
postCodeAdapter.notifyDataSetChanged();
}
}
}
这是服务的代码:
public class Part3Service extends Service {
private final String TAG = this.getClass().getSimpleName();
// TODO - we can use this as the broadcast intent to filter for in our Part3Fragment
public static final String ACTION_SERVICE_DATA_UPDATED = "com.roundarch.codetest.ACTION_SERVICE_DATA_UPDATED";
private List> data = null;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service has started");
new PostCodeRetriever().execute("http://gomashup.com/json.php?fds=geo/usa/zipcode/state/IL");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void updateData() {
// TODO - start the update process for our data
}
private void broadcastDataUpdated(String jsonString) {
Intent intent = new Intent();
intent.setAction("JSON_RECEIVED");
ArrayList postcodes = new ArrayList<>();
if (jsonString != null) {
Gson gson = new Gson();
PostCodesResult result = gson.fromJson(jsonString, PostCodesResult.class);
postcodes.addAll(result.getResult());
}
Bundle bundle = new Bundle();
bundle.putSerializable("postcodeArray", postcodes);
intent.putExtra("bundle", bundle);
sendBroadcast(intent);
stopSelf();
}
class PostCodeRetriever extends AsyncTask {
@Override
protected String doInBackground(String... params) {
Uri uri = Uri.parse(params[0]);
String jsonString = "";
try {
URL postcodesUrl = new URL(uri.toString());
InputStream inputStream = null;
HttpURLConnection connection = (HttpURLConnection) postcodesUrl.openConnection();
connection.connect();
inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
stringBuilder.deleteCharAt(0);
stringBuilder.deleteCharAt(stringBuilder.length() -1);
jsonString = stringBuilder.toString();
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
connection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonString;
}
@Override
protected void onPostExecute(String jsonString) {
broadcastDataUpdated(jsonString);
super.onPostExecute(jsonString);
}
}
}
我尝试了很多不同的东西:通过intent发送原始JSON字符串,将广播接收器定义为单独的类,将JSON转换为序列化ArrayList并通过intent发送,最后尝试将其全部包含在内捆绑并发送.
奇怪的是,非常相似的代码似乎对我的同学很好 – 我看不出他们的代码和我的代码之间可能导致问题的任何差异(他们也不能).另外,如果我试图通过意图发送一个不同的字符串然后似乎工作正常 – 广播接收器选择它并且onReceive被调用它应该是.在尝试提供此特定数据集时,似乎只会出现“无法传送广播”错误,仅适用于我!