I'm working on an aplication that allows the user to select between multiple animations before setting the selection as currently running live wallpaper.
I've reviewed links with similar questions such as: call Live wallpaper within application
And: Setting live wallpaper programmatically
They address how to make the selections, but not the error I am seeing.
The first screen dispayed to the user is a selection screen that shows multiple wallpapers. Each wallpaper has a button for the user to click which indicates the selection of that wallpaper.
Each button has a unique ID. Each is found and assigned to an instance of a Button object, and each is registered with an OnClickListener.
Once a button is clicked, I use a switch statement to determine which button was pressed, I create a new Intent, indicate which wallpaper class I want to run, and I start the activity.
When I run this in the emulator, the application loads as expected. I see my selection screen and it correctly displays the various wallpaper selections. The problem happens when I select a wallpaper to run. Once I click on a button, the display turns white and remains stuck that way until I shut down the debugger.
Having run this in debug mode, I found that after clicking on a selection button, the code performs the switch statement, runs through the creation of the intent which calls the startActivity(intent) method and then breaks. Then the code jumps through the View.java, Handler.java, and Looper.java classes where it finally loops forever in the Looper.java class in a for loop that deals with a message queue.
This is the MainActivity where I set the initial layout view, set my buttons, and create the onClickListener:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.selection);
// Capture our buttons from the selection layout
Button button_1 = (Button)findViewById(R.id.set1);
button_1.setOnClickListener(this);
// Capture our buttons from the selection layout
Button button_2 = (Button)findViewById(R.id.set2);
button_2.setOnClickListener(this);
// Capture our buttons from the selection layout
Button button_3 = (Button)findViewById(R.id.set3);
button_3.setOnClickListener(this);
}
// Implement the OnClickListener callback
public void onClick(View v) {
switch(v.getId())
{
//If button_1 was selected, set the first wallpaper.
case R.id.set1 :
setContentView(R.layout.activity_main);
Intent intent = new Intent(
WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, Wallpaper1.class));
startActivity(intent);
break;
//If button_2 was selected, set the second wallpaper.
case R.id.set2 :
setContentView(R.layout.activity_main);
intent = new Intent(
WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, Wallpaper2.class));
startActivity(intent);
break;
//If the Cuba button was selected, set the Cuba wallpaper.
case R.id.set3 :
setContentView(R.layout.activity_main);
intent = new Intent(
WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, Wallpaper3.class));
startActivity(intent);
break;
}
}
Here is the message loop where the execution gets stuck, iterating infinitely:
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
final Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
final long traceTag = me.mTraceTag;
if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
try {
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
The code doesn't seem to notice the click event until after correctly moving through the switch statement.
How can I get this to call the Intent correctly?