I have extended the Android.Application class so that I can keep state (using the application as the singleton).
However, I now want to use the Sugar ORM library to simplify my DB access, but the Sugar docs (http://satyan.github.io/sugar/getting-started.html) require that I specify 'SugarApp' as my application class in AndroidManifest.xml.
Which clashes with my Application class that extends Android Application.
Is there an alternative approach?
From the Sugar docs:
E.g. by changing the android:name attribute of the application tag.
<application android:label="#string/app_name" android:icon="#drawable/icon"
android:name="com.orm.SugarApp">
.
.
<meta-data android:name="DATABASE" android:value="sugar_example.db" />
<meta-data android:name="VERSION" android:value="2" />
<meta-data android:name="QUERY_LOG" android:value="true" />
<meta-data android:name="DOMAIN_PACKAGE_NAME" android:value="com.example" />
.
.
</application>
Answering my own question -tut tut ;-)
It's simple, I just changed my Custom App class to extend SugarApp instead of Android.Application, as SugarApp itself extends android app!
If you take a look at SugarApp class, you will find that it extends Application class overriding the onCreate() & onTerminate() methods doing its scaffolding:
#Override
public void onCreate() {
super.onCreate();
SugarContext.init(this);
}
#Override
public void onTerminate() {
super.onTerminate();
SugarContext.terminate();
}
The only thing you have to do if you want to keep your base application class is to add those method calls to your custom class.
In this way, you can maintain your custom application class instead of extending SugarApp class.
Related
I'm trying to implement a multi-module app structure with navigation between modules. The challenge Im having is doing this with a structure that contains nested fragment containers.
Background:
The design uses a single activity.The main activity layout comprises of an actionbar and fragment container. This container is used to host the different 'main' module fragment.
<androidx.fragment.app.FragmentContainerView
android:id="#+id/frg_main_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/nav_graph_app" />
Each module has a single 'parent' like fragment with a fragment container and bottomNavbar. This fragment container is used to host the detail fragments of each module and is the home fragment in the modules nav graph.
<androidx.fragment.app.FragmentContainerView
android:id="#+id/frg_home_contacts_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="false"
app:navGraph="#navigation/nav_graph_contacts" />
The app module contains a top level nav graph linking each modules parent fragment (these are not nested graphs or the modules nav graph, as the module's detail fragments are not used in the apps container view).
Each module has a bottom level nav graph linking the detail fragments of that module. This is used in conjunction with the bottomNavbar to navigate between module fragments [works].
For example, the goal is to have a button, on the home screen of the home module, that when clicked moves the user to a screen within another module, such as the contacts list screen in the Contact module.
There are two actions:
Navigate the Main container to the new module home fragment. (managed by the navContorller in the App)
Navigate the module container to the new details fragment. (managed by the navController in the module)
Presently I'm working with interfaces and trying to inject (hilt) into the main activity to achieve no.1. However, I'm always running into issues that the home module cant see the apps nav_graph or there are missing dependencies (i.e. it wants the dependency to get the nav_graph). I believe a simlar process should work between fragments for no.2
Concept reference: https://itnext.io/multi-module-navigation-in-android-63cb9924ffbd
This following code is functional when R.id.nav_graph_home but for links outside the module i.e. R.id.nav_graph_contacts it isnt.
interface HomeModuleNavInterface {
fun gotoContacts(navController: NavController)
}
class HomeModuleNavContract : HomeModuleNavInterface {
override fun gotoContacts(navController: NavController) {
navController.navigate(R.id.nav_graph_contacts)
}
}
#Module
#InstallIn(SingletonComponent::class)
class HomeNavigator {
#Singleton
#Provides
fun providesHomeNavInterface(): HomeModuleNavContract = HomeModuleNavContract()
}
class FragmentHomeNavigation : Fragment(R.layout.fragment_home_navigation) {
...
#Inject
lateinit var homeModuleNavigation: HomeModuleNavContract
...
btnContact.setOnCLickListener{
homeModuleNavigation.gotoContacts(findNavController())
}
}
Any suggestions or direction is appreciated. Thanks.
I have an advice class that makes use of another class that's part of the agent jar, but this other class has a dependency on a class that's not present in the agent jar. This class that's not present in the agent jar is present in another jar that's on the application class loader. The agent jar is on the system class loader. So I run into NoClassDefFoundError. I have tried using Transformer.ForAdvice as suggested in this other post, but that only works for the advice class.
// In agent jar on system class loader
MyAdviceClass {
#Advice.OnMethodEnter
public static void onMethodEnter() {
YetAnotherClass.doSomething(); // works fine as Transformer.ForAdvice makes use of the correct class loader while inlining this code
AnotherClass.doSomething(); // NoClassDefFoundError happens inside this method call
}
}
// In agent jar on system class loader
public class AnotherClass {
public static void doSomething() {
YetAnotherClass.doSomething(); // NoClassDefFoundError happens here because the system class loader is used to load YetAnotherClass, but that class is only present on the application class loader
}
}
// In user jar on application class loader
public class YetAnotherClass {
public static void doSomething() {
// do something else
}
}
Transform looks like this:
.transform(new AgentBuilder.Transformer
.ForAdvice()
.include(getClass().getClassLoader())
.advice(methodMatcher, "com.something.advice.MyAdvice.class"));
MyAdviceClass and AnotherClass are present in the agent jar. YetAnotherClass is present in user jar that's not on the system class loader, its on the application class loader. How can I solve this problem? i.e. is there a way by which I can force the use of the application class loader in AnotherClass?
I assume that AnotherClass is not visible from the class being instrumented. In this case, you should not include the class in ypur agent jar but place it in a seperate jar that you append to the boot loader via Instrumentation.appendToBootSearchPath. Classes on the boot loader are universally visible and should therefore be accessible to your instrumented class.
If the injected classes reference classes of the instrumented class loader you might however need to inject classes into the class loader using a ClassInjector.
I'm building UWP app with MVVMLight and I have problem with my ViewModelLocator in Design Mode.
I created ViewModelLocator:
public class ViewModelLocator
{
public MainPageViewModel Main =>ServiceLocator.Current.GetInstance<MainPageViewModel>();
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainPageViewModel>();
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IMainPageDataService, DesignMainPageDataService>();
}
else
{
SimpleIoc.Default.Register<IMainPageDataService, MainPageDataService>();
}
}
}
And then I declared it as App resource:
<Application.Resources>
<ResourceDictionary>
<viewModels:ViewModelLocator x:Key="Locator"></viewModels:ViewModelLocator>
</ResourceDictionary>
</Application.Resources>
It should work now and I should have possibility to define MainPageViewModel as MainPage DataContext but Intellisense is underlining
<viewModels:ViewModelLocator x:Key="Locator"></viewModels:ViewModelLocator>
with error
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I noticed that when I'm not using ViewModelBase.IsInDesignModeStatic property it works properly and I can see design data at MainPage.
Something like this works:
public class ViewModelLocator
{
public MainPageViewModel Main =>ServiceLocator.Current.GetInstance<MainPageViewModel>();
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainPageViewModel>();
SimpleIoc.Default.Register<IMainPageDataService, DesignMainPageDataService>();
}
}
Have you any ideas to resolve this weird problem?
Well... it was something wrong with my environment. I checked it on another machine and it works flawless.
I ran into this same issue and finally fixed it by using the native UWP Windows.ApplicationModel.DesignMode.DesignModeEnabled and now all is working well.
Additionally, I am in the process of switching to Prism, unclear if this is a VS/Blend issue, or an MVVMLight issue, but slowing finding more items I find easier to use and more robust about Prism 6, such as its Validation for example.
I have an Adobe AIR ANE that builds and runs fine on iOS. I want to run this app in the AIR simulator, but with an actionscript version of the native ANE.
Reading the docs, it seems like a default profile would be perfect for this.
I added the default profile to the extension.xml file. I added a AS implementation of the native interface to every project in my workspace. I have made methods static/not static, etc. I have tried everything but I keep getting this error:
ArgumentError: Error #3500: The extension context does not have a method with the name
I am at a complete loss. Here are the relevant files:
extension.xml
<extension xmlns="http://ns.adobe.com/air/extension/3.1">
<id>com.novel.analytics.ext.ApsalarNativeInterface</id>
<versionNumber>0.0.0</versionNumber>
<platforms>
<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libApsalarNativeInterface.a</nativeLibrary>
<initializer>ExtInitializer</initializer>
<finalizer>ExtFinalizer</finalizer>
</applicationDeployment>
</platform>
<platform name="default">
<applicationDeployment/>
</platform>
</platforms>
</extension>
My AS implementation:
package com.novel.analytics.ext
{
public class ApsalarNativeInterface
{
public function ApsalarNativeInterface()
{
}
private static function initExtension():void
{
}
public function initApsalar(apiKey:String, secret:String):void
{
}
}
}
my native interface:
package com.novel.analytics
{
import flash.external.ExtensionContext;
public class ApsalarInterface
{
private static const EXTENSION_ID : String = "com.novel.analytics.ext.ApsalarNativeInterface";
private var context : ExtensionContext;
public function ApsalarInterface()
{
this.context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
}
public function initApsalar(apiKey:String, secret:String):void
{
context.call("initApsalar", apiKey, secret);
}
}
}
Here is my adt command line (library.swf is the lib that contains the two above files:
/Applications/Adobe\ Flash\ Builder\ 4.6/sdks/4.6.0/bin/adt -package -target ane ../../$PRODUCT_NAME.ane extension.xml -swc NativeInterface.swc -platform iPhone-ARM -C . library.swf -platform default -C . library.swf
Like I said, I am at a complete loss on this one.
Sorry for the much delayed response, but I think you'd benefit from checking out this wonderful tutorial:
http://www.digitalprimates.net/author/nweber/2012/04/10/building-a-native-extension-part-3/
Based on your code snippets above, it looks like you're trying to define your pure-ActionScript implementation in a different package, with a different classname. Seems you actually want to use the same package+class+method names and just store it in a different library (so it's bundled as its own SWF). Then you tell ADT how to bundle things.
I am creating a new WPF project and we use Microsoft Unity as DI.
I am having a user control which is calling a 3rd party service.
So now how to inject dependency from the main window XAML for the usercontrol.
You can use the service locator pattern. I use it with Unity as a DI.
internal class ServiceLocator
{
[...]
public MainViewModel Main { get { return container.Resolve<MainViewModel>(); } }
}
You can intantiate your class the way you want (DI or not, the class initializes the DI etc...).
In your App.xaml
<Application.Resources>
<vm:ServiceLocator x:Key="Locator"/>
</Application.Resources>
And now, you can set your datacontext
DataContext="{Binding Main, Source={StaticResource Locator}}"
Edit:
I found another way of doing it (among other):
Take a look at this article. In the command, you can resolve your viewmodel as you like.