当前位置: 首页 > 知识库问答 >
问题:

Android-在动态注册的广播接收器上出现“无法传送广播”错误

云鸿祯
2023-03-14

我正在尝试执行一个相对简单的任务:我有一个片段,它启动一个服务,从远程服务器拉出一些JSON。然后,我想使用broadcast将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<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();
        }
    }
}

下面是该服务的代码:

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 html" target="_blank">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);
        }
    }
}

我尝试了很多不同的方法:通过intent只发送原始JSON字符串,将广播接收器定义为一个单独的类,将JSON转换为序列化的ArrayList并通过intent发送,最后尝试将其包含在一个bundle中并发送。

奇怪的是,非常相似的代码对我的同学来说似乎很好用--我看不出他们的代码和我的代码有什么不同,这可能导致了问题(他们也看不出)。此外,如果我试图通过interpent发送一个不同的字符串,那么这似乎可以很好地工作--广播接收器接收到它,并按其应有的方式调用onReceive。“无法传递广播”错误似乎只在尝试传递此特定数据集时才会发生,并且只针对我!

共有1个答案

楚岳
2023-03-14

我也有这个问题。我发现我广播的意图是巨大的数据量(这是一个很大的字节数组..)所以我通过减小字节数组的大小来解决它。快看!

 类似资料:
  • 我是android新手。我的项目有一个活动和一个服务。我的服务有一个广播接收器,而活动有一个广播发送器,它在PeriodSender方法中。动态地,当我注册接收者时,在服务开始时它不会调用,但是如果我在几分钟后发送了一些东西,它就会调用。但是我想在清单中注册它,我已经在清单中包含了接收方的详细信息,但是接收方没有调用。我的接收方类名是MyReceiver21,意图操作是My_ACTION1。实际上

  • 问题内容: 有人可以解释和之间的确切区别吗? 在什么情况下我们必须使用每个Receiver类? 问题答案: 和之间只有一个区别。 当您收到内部广播方法时, 假设, BroadcastReceiver : 它 不保证 该 CPU将保持清醒 ,如果你启动一些长时间运行的进程。CPU可能会立即回到睡眠状态。 WakefulBroadcastReceiver : 这是 保证 该 CPU将保持清醒 ,直到你

  • 本文向大家介绍Android的广播Receiver动态注册和静态注册示例,包括了Android的广播Receiver动态注册和静态注册示例的使用技巧和注意事项,需要的朋友参考一下 广播接收器注册一共有两种形式 : 静态注册和动态注册. 两者及其接收广播的区别: 1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低。 2.动态注册广播不是 常驻型

  • 本文向大家介绍Android中的广播和广播接收器代码实例,包括了Android中的广播和广播接收器代码实例的使用技巧和注意事项,需要的朋友参考一下 BroadcastReceiver不仅可以接收系统广播,也可接收自定义的广播   1.定义一个广播接收器   2.发送广播,定义好action标志,用Intent发送 3.注册只接收指定action的广播接收器 4.取消该广播接收器

  • 问题内容: 我想实现一个侦听器,如果有人从任何应用程序复制了任何东西,它将监听。 我听说有哪个将侦听复制操作,但这不是接收方(据我了解)。我有一个示例应用程序,该应用程序背后的逻辑是,从系统启动启动服务并运行一个服务,该服务将侦听“复制”操作,但是我认为这会耗尽电池。我对吗? 因此,我该如何实现可以监听复制动作的广播接收器。 问题答案: 这是监听器: 只需注册:

  • 我目前正在使用SharedReferences跟踪通过AlarmManager启动的BroadcastReceiver中要执行工作的项列表。除了一个特定的场景外,一切都很好。当我触发一个新项目来执行工作时,让它完成工作,然后删除该项目(全部通过SharedReferences编辑),它在应用程序运行时工作得很好。当列表中没有任何内容,我打开任务管理器并终止应用程序时,该项突然出现在Broadcas