sendBroadcast w oddzielnym wątku service'u

0

Witam. Pisza pewną aplikacje na platformę Android.
Informacje ogolne:
Aplikacja łączy się z serwerem za pomocą socketów. Posiada klase Polaczenie (rozszerzającą service), która jest odpowiedzialna za utrzymanie połączenia. Aplikacja w pewnym momencie musi zacząć nasłuchiwać informacji z serwera nie blokując przy tym komunikacji. Moim pomysłem było stworzenie osobnego wątku w tej usłudze. Poniżej kod klasy takiego wątku która startuje w odpowiednim miejscu klasy Polaczenie.

class Nasluch extends Polaczenie implements Runnable {
    ObjectInputStream in = null;

    public Nasluch(ObjectInputStream in) {
		 this.in = in;
	}
   
	public void run() {
		boolean test;
		System.out.println("Nasluch rozpoczety");
		while(true){
			try {
				Object o = (Object) in.readObject();
				if(((MsgPack)o).czyZgloszenie){
					System.out.println("Przyszło zgłoszenie");
					test = true;
					try {
						Intent intent = new Intent();
				        intent.setAction("test");
				        intent.putExtra("test", test);
				        sendBroadcast( intent );
					} catch (Exception e) {
						System.out.println("nie wyslalem komunikatu z servicu");
					}
					
				}
				break;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Nie moge zlapac obiektu zdarzenia");
			}
    	}
		
	}
} 

W pierwszej kolejności implementowałem do niej tylko interfejs Runnable, jednak w późniejszym czasie zostałem zmuszony (a właściwie pchnięty desperacją) do tego aby klasa ta rozszerzała moją klase Polaczenie.
Ogólnie sam wątek działa bez większych zarzutów. Problem pojawia się gdy chce wysłać informację o fakcie pojawienia się zdarzenia do mojej aktywności.

Jeśli się przyda to ta część aktywności odpowiedzialna za "łapanie":

w onCreate:

LocalBroadcastManager.getInstance(this).registerReceiver(
	                mMessageReceiver, new IntentFilter("test")); 

Sam mMessageReceiver:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
	        @Override
	        public void onReceive(Context context, Intent intent) {
	            String action = intent.getAction();
	            boolean test = intent.getBooleanExtra("test", false);
	            if(test){
	            	Toast.makeText(getBaseContext(), "Jest zgloszenie", Toast.LENGTH_LONG).show();
	            }
	        }
	    }; 

Na konsole mam wyrzucany komunikat "nie wyslalem komunikatu z servicu".
Czy ktoś mógłby mnie nakierować na to gdzie robię błąd?

0

Polecam skorzystać z IntentService i w metodzie onHandleIntent() wysyłać brodcast.
Natomiast w samym broadcascie dopisałbym jeszcze coś takiego

Bundle bundle = intent.getExtras();

i to :

boolean test = intent.getBooleanExtra("test", false);
zamienił na:
boolean test = bundle.getBooleanExtra("test", false);

A Twoja akcja i tak nie jest rozpoznawana bo masz źle if'a zrobionego.

 if (intent.getAction(ACTION_NAME){
          TOAST.makeText(context, "AKCJA", Toast.LENGTH_SHORT).show(); //pisane z pamięci więc mogą być błędy
} 
0

Witaj. Dziękuje za odpowiedź. Tylko czy w przypadku użycia IntentService nadal będę mógł "podpinać" swojego service do różnych aktywności dzięki onBind? Mam konieczność wykonywania metod z serwisu w różnych aktywnościach. (logowanie w jednej, rejestracja w innej itd). Moim pomysłem było stworzenie service w celu utrzymaniu połączenia z gniazdem serwera i wysyłania dzięki niemu różnych danych. Service odpowiada też za obsługę wątku nasłuchu w czasie ciągłym (również gdy aplikacja pracuje w tle)

0

Jeśli stworzysz sobie IntentService z repozytoriów Eclipse czy Android Studio to w tym service otrzymasz dwie metody publiczne dzięki którym będziesz się mógł komunikować z service z każdego miejsca.
Oprócz tego IntentService ma jedną przewagę nad Service. Przy tworzeniu IntentService startuje Ci to wszystko w nowym wątku, więc odpada Ci ręczne tworzenie wątku.

0

Jeśli stworzysz sobie IntentService z repozytoriów Eclipse
Mógłbyś to rozjaśnić lub jakiś link podrzucić? Z tym wątkiem chodzi o to, że muszę już w samym service mieć oddzielny wątek. Samo service nie jest oddzielnym wątkiem?

0

To jest wygenerowany IntentService z Eclipse.

package com.example.rssreader;

import android.app.IntentService;
import android.content.Intent;
import android.content.Context;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p>
 * TODO: Customize class - update intent actions, extra parameters and static
 * helper methods.
 */
public class MyIntentService extends IntentService {
	// TODO: Rename actions, choose action names that describe tasks that this
	// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
	private static final String ACTION_FOO = "com.example.rssreader.action.FOO";
	private static final String ACTION_BAZ = "com.example.rssreader.action.BAZ";

	// TODO: Rename parameters
	private static final String EXTRA_PARAM1 = "com.example.rssreader.extra.PARAM1";
	private static final String EXTRA_PARAM2 = "com.example.rssreader.extra.PARAM2";

	/**
	 * Starts this service to perform action Foo with the given parameters. If
	 * the service is already performing a task this action will be queued.
	 * 
	 * @see IntentService
	 */
	// TODO: Customize helper method
	public static void startActionFoo(Context context, String param1,
			String param2) {
		Intent intent = new Intent(context, MyIntentService.class);
		intent.setAction(ACTION_FOO);
		intent.putExtra(EXTRA_PARAM1, param1);
		intent.putExtra(EXTRA_PARAM2, param2);
		context.startService(intent);
	}

	/**
	 * Starts this service to perform action Baz with the given parameters. If
	 * the service is already performing a task this action will be queued.
	 * 
	 * @see IntentService
	 */
	// TODO: Customize helper method
	public static void startActionBaz(Context context, String param1,
			String param2) {
		Intent intent = new Intent(context, MyIntentService.class);
		intent.setAction(ACTION_BAZ);
		intent.putExtra(EXTRA_PARAM1, param1);
		intent.putExtra(EXTRA_PARAM2, param2);
		context.startService(intent);
	}

	public MyIntentService() {
		super("MyIntentService");
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		if (intent != null) {
			final String action = intent.getAction();
			if (ACTION_FOO.equals(action)) {
				final String param1 = intent.getStringExtra(EXTRA_PARAM1);
				final String param2 = intent.getStringExtra(EXTRA_PARAM2);
				handleActionFoo(param1, param2);
			} else if (ACTION_BAZ.equals(action)) {
				final String param1 = intent.getStringExtra(EXTRA_PARAM1);
				final String param2 = intent.getStringExtra(EXTRA_PARAM2);
				handleActionBaz(param1, param2);
			}
		}
	}

	/**
	 * Handle action Foo in the provided background thread with the provided
	 * parameters.
	 */
	private void handleActionFoo(String param1, String param2) {
		// TODO: Handle action Foo
		throw new UnsupportedOperationException("Not yet implemented");
	}

	/**
	 * Handle action Baz in the provided background thread with the provided
	 * parameters.
	 */
	private void handleActionBaz(String param1, String param2) {
		// TODO: Handle action Baz
		throw new UnsupportedOperationException("Not yet implemented");
	}
}
 

poza tym patrząc w źródła IntentService (linijka 107)
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/app/IntentService.java
nie dostrzegam czegoś takiego w Service

1 użytkowników online, w tym zalogowanych: 0, gości: 1