ustwo / clockwise Goto Github PK
View Code? Open in Web Editor NEWWatch face framework for Android Wear developed by ustwo
Home Page: wear.ustwo.com
License: MIT License
Watch face framework for Android Wear developed by ustwo
Home Page: wear.ustwo.com
License: MIT License
Hi guy, Thanks for the excellent work for this great library. it helps me a lot. But I am wondering about the supporting interactive on our library. Do you guys have plan for it yet?
Add more support for useful/common time/date formatters and time localization.
Create new gradle file/task to install to Maven.
Time class will be deprecated in API level 22. Framework should remove its dependency on the Time class.
System time: 17:20:56.887 Reported seconds: 56.91
System time: 17:20:56.921 Reported seconds: 56.94
System time: 17:20:56.953 Reported seconds: 56.97
System time: 17:20:56.987 Reported seconds: 56.01 ****
System time: 17:20:57.020 Reported seconds: 57.04
System time: 17:20:57.053 Reported seconds: 57.07
One of the last sources of excessive object allocation during rendering is this ScheduledExecutorService
being used in WatchFace
:
private class WatchFaceEngine extends WatchFaceService.Engine {
private final ScheduledExecutorService mScheduledTimeUpdaterPool = Executors.newScheduledThreadPool(2);
This creates a java.util.concurrent.locks.AbstractQueuedSynchronizer.Node
every time the timer fires, which seems to be unavoidable and something to do with managing the queue of tasks.
Perhaps switching to java.util.Timer
would resolve this problem.
"Add watch face with 3rd party weather data to list of samples to show how to currently integrate data using the ConnectedWatchFace and WearableApiHelper.
NOTE: we will want to update this watch face once Clockwise is updated to provide support for data integration."
I'm using toMillis
to interact with Joda Time which is arguably unnecessary now but part of how I was previously doing my computation.
I had my interactive update rate set to 33ms but my hands were only moving once a second.
It turned out that WatchFaceTime#toMillis(boolean)
was always returning a multiple of 1000. The workaround is just to add the millis back onto the value before passing it off.
Add support for integrating data from the companion application (e.g. 3rd party data) into the watch face via the ConnectedWatchFace and WearableApiHelper.
Currently, ConnectedWatchFace creates a WearableAPIHelper (which wraps a GoogleApiClient) necessary for interacting with the data, message and node APIs.
However, derived classes have no way of determining if the API client is ready, became suspended, or otherwise failed. Additionally, subscribing to all APIs (data, message, node) may be unnecessary for most watch faces and therefore can produce overhead.
Lastly, exposing putMessage and putDataItem as the only ways to interact with the APIs is insufficient in many cases. This could be fine, but would require the watch face to create its own API client (or helper), increasing overhead and making the value of ConnectedWatchFace questionable in many common scenarios (for example, watch face only needs to store data in the local node, or needs to know whether the API client is connected, or needs to see connected nodes)
Add support for custom watch face configuration on the wearable as well as the companion application and handle synchronization between them.
WatchFace#onTimeChanged
is currently implemented as follows:
protected void onTimeChanged(WatchFaceTime oldTime, WatchFaceTime newTime) {
Logr.v(String.format("WatchFace.onTimeChanged: oldTime=%d; newTime=%d",
oldTime.millis, newTime.millis));
}
This performs string formatting which involves allocation of new char[]
and String
objects on every render cycle, irrespective of whether this event is being logged. The symptom is stuttering when rendering in interactive mode. By modifying my overridden method such that it no longer calls super.onTimeChanged
, my rendering has become much smoother.
It should probably at least check whether the event will be logged before doing the concatenation. I see similar things going on in onWatchModeChanged
and others, but those don't seem to be called anywhere near as often.
When switching between watchfaces, often causes an exception:
06-09 16:47:00.203 6048-6048/com.dexdrip.stephenblack.nightwatch E/ActivityThread﹕ Service com.dexdrip.stephenblack.nightwatch.LargeHome has leaked IntentReceiver android.support.wearable.watchface.WatchFaceService$Engine$1@371daab0 that was originally registered here. Are you missing a call to unregisterReceiver()?
My idea why this could happen:
Every time, a Watchface gets instantiated, it creates a new Engine (Line 56)
Aparently "onCreate()" is called as it registers the Receiver (Line 281), but "onDestroy()" might be not..
WatchFace#updateTimeAndInvalidate
is implemented as follows:
private void updateTimeAndInvalidate() {
mPreviousTime.set(mLatestTime);
mLatestTime.setToNow();
mLatestTime.timezone = TimeZone.getDefault().getID();
onTimeChanged(mPreviousTime, mLatestTime);
boolean is24Hour = DateFormat.is24HourFormat(this);
if(is24Hour != mIs24HourFormat) {
mIs24HourFormat = is24Hour;
on24HourFormatChanged(mIs24HourFormat);
}
invalidate();
}
This call to TimeZone#getDefault
ultimately causes the JDK to clone the TimeZone
object, which seems to be one of the last major causes of expensive object allocation.
If it were called infrequently, this would be OK, but it's actually called for every single redraw. It should probably be reduced to only being called when the time zone actually changes.
I don't seem to have a good workaround for this, short of not using clockwise, or forking it.
ConnectedWatchFace creates and sets up API client in onCreateEngine, and destroys in onDestroy. However, creation should be done in onCreate instead of onCreateEngine (likely that was the intention), since onCreateEngine's job is to create objects, and it's not part of the same Service lifecycle as onDestroy.
Create scripts for user-friendly and automated gradle integration of clockwise modules into existing watch face projects.
Currently, the Instances projection is set to the common calendar event data (e.g. Start, End, Title, etc.) and cannot be changed.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.