I have a solution with two projects in it. A portable areas project, and a web site that references the portable areas project, and Both reference MvcContrib.

The problem I am have is with the embedded resources, they are giving me a 404 error when I try to get to them. It seems like it's trying to access a physical path not the dll. The partial view works fine.

The file I'm trying to access looks like this inside my visual studio solution explorer

AdHocReporting/Areas/AdHocReportBuilder/Content/adhoc.css (the build action is embedded)

**Here is the routing for the portable area:**

```
using System.Web.Mvc;
using MvcContrib.PortableAreas;

namespace AdHocReporting.Areas.AdHocReportBuilder
{
    public class AdHocReportBuilderAreaRegistration : PortableAreaRegistration
    {
        public override string AreaName
        {
            get { return "AdHocReportBuilder"; }
        }

        public override void RegisterArea(AreaRegistrationContext context, IApplicationBus bus)
        {
            RegisterRoutes(context);
            RegisterAreaEmbeddedResources();

        }
        private void RegisterRoutes(AreaRegistrationContext context)
        {
            context.MapRoute(
              AreaName + "_content",
              base.AreaRoutePrefix + "/Content/{resourceName}",
              new { controller = "EmbeddedResource", action = "Index", resourcePath = "Content" },
              new[] { "MvcContrib.PortableAreas" }
          );

            context.MapRoute(
                AreaName + "_default",
                base.AreaRoutePrefix + "/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

```

**Here is the Web sites Global.aspx that has the reference to the portable area**

```
namespace AdHocReportingSite
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

        }
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            PortableAreaRegistration.RegisterEmbeddedViewEngine();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
        }
    }
}

```

**here is an image of what my solution explore looks like:**

![Solution Explorer](https://i.stack.imgur.com/6P0TK.png)
['https://Stackoverflow.com/questions/14695580', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/937294/']
Clyde's solution works, but it is a broadcast, which I am pretty sure will be less efficient than calling a method directly. I could be mistaken, but I think the broadcasts are meant more for inter-application communication.

I'm assuming you already know how to bind a service with an Activity.
I do something sort of like the code below to handle this kind of problem:

```
class MyService extends Service {
    MyFragment mMyFragment = null;
    MyFragment mMyOtherFragment = null;

    private void networkLoop() {
        ...

        //received new data for list.
        if(myFragment != null)
            myFragment.updateList();
        }

        ...

        //received new data for textView
        if(myFragment !=null)
            myFragment.updateText();

        ...

        //received new data for textView
        if(myOtherFragment !=null)
            myOtherFragment.updateSomething();

        ...
    }
}

class MyFragment extends Fragment {

    public void onResume() {
        super.onResume()
        //Assuming your activity bound to your service
        getActivity().mMyService.mMyFragment=this;
    }

    public void onPause() {
        super.onPause()
        //Assuming your activity bound to your service
        getActivity().mMyService.mMyFragment=null;
    }

    public void updateList() {
        runOnUiThread(new Runnable() {
            public void run() {
                //Update the list.
            }
        });
    }

    public void updateText() {
       //as above
    }
}

class MyOtherFragment extends Fragment {
             public void onResume() {
        super.onResume()
        //Assuming your activity bound to your service
        getActivity().mMyService.mMyOtherFragment=this;
    }

    public void onPause() {
        super.onPause()
        //Assuming your activity bound to your service
        getActivity().mMyService.mMyOtherFragment=null;
    }

    public void updateSomething() {//etc... }
}

```

I left out bits for thread safety, which is essential. Make sure to use locks or something like that when checking and using or changing the fragment references on the service.
You could use android Jetpack's [LiveData](https://developer.android.com/topic/libraries/architecture/livedata)

As per the documentation:

> 
> You can extend a `LiveData` object using the singleton pattern to wrap
> system services so that they can be shared in your app. The LiveData
> object connects to the system service once, and then any observer that
> needs the resource can just watch the LiveData object. For more
> information, see [Extend
> LiveData](https://developer.android.com/topic/libraries/architecture/livedata?hl=en#extend_livedata).
> 
> 
> 

Below is what I did for communication between Service and Activity and also Service and Fragment.

In this example, I have:

* a class `SyncLogLiveData` extending `LiveData` that contains a `SpannableStringBuilder`
* a service `SyncService`
* a fragment `SyncFragment`

The Fragment "observes" the LiveData (ie SyncLogLiveData) and performs an action when the LiveData changes.  

The LiveData is updated by the Service.  

I could also update the LiveData from the Fragment in the same way but don't show it here.

**class `SyncLogLiveData`**

```java
public class SyncLogLiveData extends LiveData<SpannableStringBuilder> {
    private static SyncLogLiveData sInstance;
    private final static SpannableStringBuilder log = new SpannableStringBuilder("");

    @MainThread
    public static SyncLogLiveData get() {
        if (sInstance == null) {
            sInstance = new SyncLogLiveData();
        }
        return sInstance;
    }

    private SyncLogLiveData() {
    }

    public void appendLog(String text) {
        log.append(text);
        postValue(log);
    }

    public void appendLog(Spanned text) {
        log.append(text);
        postValue(log);
    }
}

```

**in class `SyncService`**

This line of code will update the content of the LiveData

```java
SyncLogLiveData.get().appendLog(message);

```

You could also make direct use of `setValue(...)` or `postValue(...)` methods of `LiveData`

```java
SyncLogLiveData.get().setValue(message);

```

**class SyncFragment**

```java
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {

    //...

    // Create the observer which updates the UI.
    final Observer<SpannableStringBuilder> ETAObserver = new Observer<SpannableStringBuilder>() {
        @Override
        public void onChanged(@Nullable final SpannableStringBuilder spannableLog) {
            // Update the UI, in this case, a TextView.
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textViewLog.setText(spannableLog);
                }
            });
        }
    };
    // Observe the LiveData, passing in this activity/fragment as the LifecycleOwner and the observer.
    SyncLogLiveData.get().observe(getViewLifecycleOwner(), ETAObserver);

    //...
}

```

From within an activity it works the same way, but for `.observe(...)`, you may use this instead

```java
SyncLogLiveData.get().observe(this, ETAObserver);

```

You could also fetch the current value of the LiveData this way at anytime in your code.

```java
SyncLogLiveData.get().getValue();

```

Hopefully this will help someone. There wasn't any mention of LiveData in this answer yet.