비교적 간단한 작업을 수행하려고합니다. 원격 서버에서 JSON을 가져 오는 서비스를 시작하는 프래그먼트가 있습니다. 그런 다음 JSON을 브로드 캐스트를 사용하여 원래의 호출 단편으로 다시 전달하려는 경우 BroadcastReceiver가 단편의 익명 클래스로 정의됩니다. 그러나Android - 동적으로 등록 된 브로드 캐스트 수신기에서 브로드 캐스트를 전달할 수 없음 오류가 발생했습니다.
, 나는이 작업을 수행하려고 할 때마다, 나는 다음과 같은 오류가 계속 : 여기
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<PostCodesResult.Result> postcodes = (ArrayList<PostCodesResult.Result>) bundle.getSerializable("postcodeArray");
updatePostcodes(postcodes);
}
};
intentFilter = new IntentFilter("JSON_RECEIVED");
getActivity().registerReceiver(receiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
}
private void updatePostcodes(ArrayList<PostCodesResult.Result> postcodes) {
if (postcodes.size() > 0){
postCodeAdapter = new PostCodeAdapter(getActivity(), R.layout.part3_listview_item, postcodes);
listView.setAdapter(postCodeAdapter);
postCodeAdapter.notifyDataSetChanged();
}
}
}
그리고 다음은
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 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<Map<String, String>> 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<PostCodesResult.Result> 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<String, Void, String> {
@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);
}
}
}
나는 의도를 통해 원시 JSON 문자열을 보내고, 브로드 캐스트 리시버를 별도의 클래스로 정의하고, JSON을 직렬화 된 ArrayList로 변환하고, 의도를 통해 보내고, 마지막으로 시도하고있다. 그것을 묶음으로 모두 포함시키고 보내는 것.
기괴한 것은 내 급우에게 아주 비슷한 코드가 잘 작동하는 것 같습니다. 문제를 일으킬 수있는 코드와 내 코드 사이에 차이점을 볼 수 없습니다. 또한, 의도를 통해 다른 String을 보내려고하면 잘 작동하는 것처럼 보입니다. 방송 수신자가 수신하고 onReceive를 호출해야합니다. '브로드 캐스트를 전달할 수 없습니다.'라는 오류는이 특정 데이터 집합을 전달하려고 할 때 발생하는 것으로 보입니다.
은'PostCodesResult.Result'가 직렬화 가능합니까? – nandsito
예, 내부 클래스와 외부 클래스 모두 직렬화 가능합니다. –
나는 그것이 문제의 원인인지는 모르겠지만 귀하의 단편에 몇 가지 이슈가 있습니다. 수신자를 이중 등록하고 (Frag가 다시 시작될 때까지) 등록이 취소되지는 않습니다. 그리고 수신기는 활동에 등록됩니다. 현재 Frag 나 그 액티비티가 화면을 벗어나면 수신자는 어떻게됩니까? – nandsito