Невозможно запустить Сервис с намерением, вызванным «NetworkOnMainThreadException» - PullRequest
0 голосов
/ 08 апреля 2020

Я работаю с изображениями для отправки на устройство, которое работает нормально, когда я использую Asyn c Задача, она работает хорошо, но проблема в том, что когда я делаю это через Службу, она не работает, и я получаю эту ошибку, "Невозможно запустить Сервис с намерением, вызванным" NetworkOnMainThreadException "". Я фактически передаю байт [] из MainActivity в Service, мне нужно использовать сервис, потому что метод OnReceive BroadcastReceiver не может ответить на задачу Asyn c.

Спасибо!

В Mainfest. xml

 <service android:name=".SendImageClientService"/>

MainActivity


    private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int wifiStateExtra = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                    WifiManager.WIFI_STATE_UNKNOWN); 

            if(wifiStateExtra==WifiManager.WIFI_STATE_ENABLED){
               sendingDrawableImage();
            }else if(wifiStateExtra==WifiManager.WIFI_STATE_DISABLED){
                Toast.makeText(context, "Please Check Your Internet Connection", Toast.LENGTH_SHORT).show();
            }

        }
    };

      private void sendingDrawableImage() {

        drawable = (BitmapDrawable) imageView.getDrawable();
        bitmap = drawable.getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
        byte[] array = byteArrayOutputStream.toByteArray();

        Intent serviceIntent=new Intent(this,SendImageClientService.class);
        serviceIntent.putExtra("byte",array);
        this.startService(serviceIntent);
        }

  @Override
    protected void onStart() { 
        super.onStart();
        IntentFilter intentFilter = new 
        IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); 
        registerReceiver(wifiStateReceiver, intentFilter);
    }

Класс обслуживания


public class SendImageClientService extends Service {

    Handler handler = new Handler(Looper.getMainLooper());

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {

            byte[] bytesss=intent.getByteArrayExtra("byte");

            Socket socket = new Socket("ip_address_here", 8888);

            OutputStream out = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(out);
            dataOutputStream.write(bytesss);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(SendImageClientService.this, "Image sent", Toast.LENGTH_SHORT).show();
                }
            });

            dataOutputStream.close();
            out.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return START_STICKY;

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

1 Ответ

0 голосов
/ 08 апреля 2020

документация гласит:

Внимание: служба запускается в главном потоке своего процесса хостинга; служба не создает свой собственный поток и не запускается в отдельном процессе, если не указано иное. Если ваш сервис будет выполнять какие-либо работы с интенсивным использованием ЦП или операции блокировки, такие как воспроизведение MP3 или работа в сети, вы должны создать новый поток в службе для завершения этой работы. Используя отдельный поток, вы можете уменьшить риск ошибок приложения не отвечающего (ANR), а основной поток приложения может оставаться выделенным для взаимодействия пользователя с вашими действиями.

https://developer.android.com/guide/components/services

поэтому вам необходимо создать новый поток в вашем сервисе для длительной работы.

Кроме того, вам нужно знать, что Сервисы используют для длинных фоновых задач, а IntentServices используя для коротких фоновых задач. Но IntentService работает в отдельном потоке.

Вы можете использовать что-то вроде этого:

new Handler().post(runnable)

, где runnable - это ваше длительное действие операции (например, действие inte rnet или действие базы данных). Обработчик - это определенный класс c для работы с потоком в android.

Edit.

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
handler.post(new Runnable() {
                @Override
                public void run() {
            byte[] bytesss=intent.getByteArrayExtra("byte");

            Socket socket = new Socket("ip_address_here", 8888);

            OutputStream out = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(out);
            dataOutputStream.write(bytesss);   

            dataOutputStream.close();
            out.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        }
        });

        return START_STICKY;

    }
...