ACRA 4 for Live Wallpaper

61 views
Skip to first unread message

lennart rolland

unread,
Nov 8, 2011, 11:07:46 AM11/8/11
to acra-discuss
Am i thick or is it actually non trivial to integrate ACRA in a live
wallpaper?

Where do I put my annotation?

--Lennart

Kevin Gaudin

unread,
Nov 8, 2011, 11:28:19 AM11/8/11
to acra-d...@googlegroups.com
I have not worked on this use case and I am not sure that you can use ACRA with live wallpapers for the moment.

If somebody has worked on this topic, please report here your findings, there have been several users complaining about the lack of support for live wallpapers.

Kevin

lennart rolland

unread,
Nov 8, 2011, 12:21:18 PM11/8/11
to acra-discuss
The problem seems to be that you can only annotate an Application
class, while a live wallpaper does not extend Application.

I see two possible solutions:

1. Allow initializing ACRA without using annotations for an arbitrary
application instance (such as the one returned from
WallpaperService.getApplication())

2. Add support for annotating classes derived from WallpaperService or
WallpaperEngine

I will try to patch the latest version, and I will make available my
changes if it is successful!

--Lennart

lennart rolland

unread,
Nov 8, 2011, 1:02:29 PM11/8/11
to acra-discuss
Ok this did it:
/**
* <p>
* Backwards compatible shortcut that initializes ACRA with an
application
* instance.
*
* @see public static <T> void init(Application app, T
annotatedClass)
*
* Initialize ACRA for a given Application. The call to this method
should
* be placed as soon as possible in the {@link
Application#onCreate()}
* method.
* </p>
* @param app
*/
public static void init(Application app) {
init(app);
}

/**
* <p>
* Initialize ACRA for a given Application and annotated class. The
call to
* this method should be placed as soon as possible in the
* {@link Application#onCreate()} method.
* </p>
*
* @param app
* Your Application class.
*/
public static <T> void init(Application app, T annotatedClass) {
mAppStartDate = new Time();
mAppStartDate.setToNow();
mApplication = app;
mReportsCrashes =
annotatedClass.getClass().getAnnotation(ReportsCrashes.class);
....

Tn you just annotate whichever class is important to you (in my case
the WallpaperService class) and initialize AGRA with
AGRA.init(getApplication(), this); in the onCreate() method of the
wallpaper service :)

--Lennart

lennart rolland

unread,
Nov 8, 2011, 1:13:46 PM11/8/11
to acra-discuss
I have created a stack overflow on this as well, that was before I set
out to patch it myself :)

http://stackoverflow.com/questions/8053019/how-can-i-use-acra-from-a-live-wallpaper

lennart rolland

unread,
Nov 8, 2011, 1:52:00 PM11/8/11
to acra-discuss
Was a bit quick here. Corrected version

/**
* <p>
* Backwards compatible shortcut that initializes ACRA with an
application
* instance.
*
* @see public static <T> void init(Application app, T
annotatedClass)
*
* Initialize ACRA for a given Application. The call to this method
should
* be placed as soon as possible in the {@link
Application#onCreate()}
* method.
* </p>
* @param app
*/
public static void init(Application app) {
init(app,app);
}

/**
* <p>
* Initialize ACRA for a given Application and annotated class. The
call to
* this method should be placed as soon as possible in the
initialization
* code of your application (for example in an onCreate() method).
* </p>
*
* @param app
* Your Application class.
* @param annotatedClass
* Your annotated class.
*/
public static <T> void init(Application app, T annotatedClass) {
mAppStartDate = new Time();
mAppStartDate.setToNow();
mApplication = app;
mReportsCrashes =
annotatedClass.getClass().getAnnotation(ReportsCrashes.class);

...


--Lennart

Kevin Gaudin

unread,
Nov 8, 2011, 5:35:05 PM11/8/11
to acra-d...@googlegroups.com
Actually, I just tested ACRA out of the box and it works.

What I did:
- Create a Wallpaper Project with the LiveCube sample project from the 2.1 SDK.
- Add an Application subclass
- Set the ReportsCrashes annotation
- Modify the manifest to add my Application class name to the name attribute of the application element
- Add the INTERNET permission

It worked.

Kevin

Kevin Gaudin

unread,
Nov 8, 2011, 5:43:53 PM11/8/11
to acra-d...@googlegroups.com
Of course, I added ACRA.init(this) in myApp.onCreate().

lennart rolland

unread,
Nov 9, 2011, 12:06:06 PM11/9/11
to acra-discuss
If I am following you correctly, you made a dummy subclass extending
your WallpaperService that you could annotate?

It would be great if you could document this!

--Lennart

On Nov 8, 11:43 pm, Kevin Gaudin <kevin.gau...@gmail.com> wrote:
> Of course, I added ACRA.init(this) in myApp.onCreate().
>
> On Tue, Nov 8, 2011 at 11:35 PM, Kevin Gaudin <kevin.gau...@gmail.com>wrote:
>
>
>
> > Actually, I just tested ACRA out of the box and it works.
>
> > What I did:
> > - Create a Wallpaper Project with the LiveCube sample project from the 2.1
> > SDK.
> > - Add an Application subclass
> > - Set the ReportsCrashes annotation
> > - Modify the manifest to add my Application class name to the name
> > attribute of the application element
> > - Add the INTERNET permission
>
> > It worked.
>
> > Kevin
>

Kevin Gaudin

unread,
Nov 9, 2011, 12:39:40 PM11/9/11
to acra-d...@googlegroups.com
Actually, I just followed the regular installation procedure and created an Application subclass which supports the Annotation and the call to ACRA.init() in its onCreate() method.

This is the standard way of integrating ACRA in any application.

Please tell us if you still have problems. I want to be sure that it covers your use case.

Kevin

lennart rolland

unread,
Nov 9, 2011, 2:08:14 PM11/9/11
to acra-discuss
But is it not so that the application subclass you annotate should
actually have some code in it that could crash? If this is not the
case then the dependence upon an application class at all would feel
very fake since you would just need a dummy application subclass.

There are no Application subclasses in the cube live wallpaper
example, only a WallpaperService and WallpaperEngine. Having to create
a dummy Application subclass here feels wrong IMO.

http://developer.android.com/resources/samples/CubeLiveWallpaper/src/com/example/android/livecubes/cube2/CubeWallpaper2.html


I hope I have missunderstood you!

--Lennart



On Nov 9, 6:39 pm, Kevin Gaudin <kevin.gau...@gmail.com> wrote:
> Actually, I just followed the regular installation procedure and created an
> Application subclass which supports the Annotation and the call to
> ACRA.init() in its onCreate() method.
>
> This is the standard way of integrating ACRA in any application.http://code.google.com/p/acra/wiki/BasicSetup?tm=6#Setting-up_your_pr...
>
> Please tell us if you still have problems. I want to be sure that it covers
> your use case.
>
> Kevin
>

Kevin Gaudin

unread,
Nov 9, 2011, 5:02:47 PM11/9/11
to acra-d...@googlegroups.com
All Android applications run with an Application object instance as a context of execution.

You rarely really need to implement your own Application subclass. Some people use them to create static fields available in any other application component (like global variables), but this not a so good idea. In most projects, whatever the type, you usually don't need one and the Android framework instantiates the default android.app.Application class.

While reading examples of crash reporter implementation, I often found instructions like "In your main Activity, call Thread.setDefaultUncaughtExceptionHandler(new YourUncaughtExceptionHandler())". But in many real applications, there is no such "main activity". There could be many other starting points for your application, like a background service, a content provider, or many different activities that are triggered by external intents.

So, in complex applications, you would have to pollute many of your classes with code to initialize your exception handler... with the risk of calling this initialization code several times if you navigate between several activities.

My idea was to attach this exception handler at the earliest possible stage in the life of an Android application, in order to report all possible errors for any component and have a single modification point.

And the earliest possible stage in an application lifecycle where we can add some code is android.app.Application.onCreate(), which is "Called when the application is starting, before any other application objects have been created."

The call to Thread.setDefaultUncaughtExceptionHandler() is like a global setting. Once you set this handler, it is applied to your whole Dalvik process. So setting it once at the very beginning of your application life ensures that any uncaught exception in any class of your application will be reported (even those coming from the android framework code).

You should not consider that subclassing Application only to put the ACRA annotation and init call is like implementing a "dummy" application class. You just should feel happy that I found some handy API concepts that allow you to manage, configure and start the whole crash reporting library for your whole app in a single class, with 2 simple lines of code. :-)

It would have required much less work for me to tell you "copy the 400 lines of code below in the Application.onCreate() method, and don't forget to replace the various hardcoded values with whatever you like" :o))))

Finally, a live wallpaper application is an application like any other android application,with a special service which can draw on a Surface provided by another application. Before it does anything, the Android System instantiates its android.app.Application class and calls its onCreate() method. There is nothing wrong with implementing an Application subclass, it is supported by the official android API and you should not feel bad about adding one to your project.

There is still one case where this init method is not enough. Some applications can make use of multiple processes (not threads, processes), and each process would need to initialize its own ACRA instance. This case is not covered with the present API.

I hope this is now clearer for you. Please do not hesitate to ask more questions so you don't have any doubt about it anymore (or to show me that I'm wrong, I don't pretend to know all the android magic).

Kevin

lennart rolland

unread,
Nov 13, 2011, 2:39:51 PM11/13/11
to acra-discuss
Thanks for clearing things up.

Again, this could with great benifit go into the documentation. I
could do it for you if you let me into the wiki.

Thanks!

--Lennart

On Nov 9, 11:02 pm, Kevin Gaudin <kevin.gau...@gmail.com> wrote:
> All Android applications run with an Application object instance as a
> context of execution.
>
> You rarely really need to implement your own Application subclass. Some
> people use them to create static fields available in any other application
> component (like global variables), but this not a so good idea. In most
> projects, whatever the type, you usually don't need one and the Android
> framework instantiates the default android.app.Application class.
>
> While reading examples of crash reporter implementation, I often found
> instructions like "In your main Activity, call
> Thread.setDefaultUncaughtExceptionHandler(new
> YourUncaughtExceptionHandler())". But in many real applications, there is
> no such "main activity". There could be many other starting points for your
> application, like a background service, a content provider, or many
> different activities that are triggered by external intents.
>
> So, in complex applications, you would have to pollute many of your classes
> with code to initialize your exception handler... with the risk of calling
> this initialization code several times if you navigate between several
> activities.
>
> My idea was to attach this exception handler at the earliest possible stage
> in the life of an Android application, in order to report all possible
> errors for any component and have a single modification point.
>
> And the earliest possible stage in an application lifecycle where we can
> add some code is android.app.Application.onCreate(), which is
> "<goog_135775015>Called
> when the application is starting, before any other application objects have
> been created."<http://developer.android.com/reference/android/app/Application.html#o...()>
>
> The call to Thread.setDefaultUncaughtExceptionHandler() is like a global
> setting. Once you set this handler, it is applied to your whole Dalvik
> process. So setting it once at the very beginning of your application life
> ensures that any uncaught exception in any class of your application will
> be reported (even those coming from the android framework code).
>
> You should not consider that subclassing Application only to put the ACRA
> annotation and init call is like implementing a "dummy" application class.
> You just should feel happy that I found some handy API concepts that allow
> you to manage, configure and start the whole crash reporting library for
> your whole app in a single class, with 2 simple lines of code. :-)
>
> It would have required much less work for me to tell you "copy the 400
> lines of code below in the Application.onCreate() method, and don't forget
> to replace the various hardcoded values with whatever you like" :o))))
>
> Finally, a live wallpaper application is an application like any other
> android application,with a special service which can draw on a Surface
> provided by another application. Before it does anything, the Android
> System instantiates its android.app.Application class and calls its
> onCreate() method. There is nothing wrong with implementing an Application
> subclass, it is supported by the official android API and you should not
> feel bad about adding one to your project.
>
> There is still one case where this init method is not enough. Some
> applications can make use of multiple processes (not threads,
> processes<http://developer.android.com/guide/topics/fundamentals/processes-and-...>),
> and each process would need to initialize its own ACRA instance. This case
> is not covered with the present API.
>
> I hope this is now clearer for you. Please do not hesitate to ask more
> questions so you don't have any doubt about it anymore (or to show me that
> I'm wrong, I don't pretend to know all the android magic).
>
> Kevin
>
> On Wed, Nov 9, 2011 at 8:08 PM, lennart rolland <lennartroll...@gmail.com>wrote:
>
>
>
> > But is it not so that the application subclass you annotate should
> > actually have some code in it that could crash? If this is not the
> > case then the dependence upon an application class at all would feel
> > very fake since you would just need a dummy application subclass.
>
> > There are no Application subclasses in the cube live wallpaper
> > example, only a WallpaperService and WallpaperEngine. Having to create
> > a dummy Application subclass here feels wrong IMO.
>
> >http://developer.android.com/resources/samples/CubeLiveWallpaper/src/...
Reply all
Reply to author
Forward
0 new messages