I have a couple of questions regarding the getAuthToken() method of the AccountManager class.
What values can "authTokenType" take? So far I have only seen it take the value "ah".
The getAuthToken(Account,String,boolean,AccountManagerCallback, Handler) has been deprecated in favor of it's overloaded counterpart which also takes a Bundle as a parameter. What function does it serve? I read the docs but couldn't wrap my head around it.
As what in the docs says,
The auth token type, an authenticator-dependent string token, must not be null
This value should be the same as what you entered on your authenticator metadata file (res/xml/authenticator.xml) under android:accountType attribute
Related
This might be a very silly question, but I am logging the methods that are triggered in my app as strings. When an issue is submitted, I would like to automatically input the text of the strings as parameters for methods. E.g:
For method:
fun assignPot(potType: PotType, ball: DomainBall, action: PotAction) {...}
I'd like to somehow call method:
assignPot(FOUL(2, BLUE(5), SWITCH))
From String:
"FOUL(2, BLUE(5), SWITCH)"
The only workaround I can think of is to split the string and create a when -> then function to get actual classes from strings, but I wondered if there's a more concise way for this.
This is not what you want to do. You should design your app in a way that prevents users from providing input similar to actual code.
However, you can achieve this. Complex parsings like this oftenly use regex-based approaches.
As you said, you should map your string part to class. If your PotType is enum, you can do something like
val re = Regex("[^A-Za-z\s]")
val reNumbers = Regex("[^0-9\s]")
// get classes
val classNames = originalString.replace(re, "").split(" ")
// get their constructor numerical arguments
val classArgs = originalString.replace(reNumbers, "").split(" ")
After that you can implement mapping with when expression. You probably will use some collection of Any type.
As you see, this sadly leads you to parsing code by code. Concise way to solve is to implement your own script compiler/interpreter and use it in your application :) That will later lead you to dealing with security breaches and so on.
If you are logging problematic method calls and want to repeat them immediately after issue is submitted, you probably want to programatically save the calls to lambdas and call them when you receive an issue log.
I'm passing a parcelable object to a fragment by adding into a bundle while creating the fragment. In onc instance modification to this parcelled object reflects modification in original object and in another case it is not. I'm a little baffled by this behaviour.
Till now I have assumed retrieving a parcelled objects through a bundle always create new object[no sure whether it's shallow copy or deep copy].
Someone please clarify parcelable behaviour.
I was struggling with a similar issue. At the first glance it seems that we always obtain a new deep copy from the parcelled objects. Moreover, there are even some StackOverflow answers which suggest to use Parcelable interface to clone objects. All this just increases confusion regarding the subject.
Here is what I've found after a lot of searching and googling:
Take a closer look at the official Parcel documentation. Here is the important quote:
An unusual feature of Parcel is the ability to read and write active
objects. For these objects the actual contents of the object is not
written, rather a special token referencing the object is written.
When reading the object back from the Parcel, you do not get a new
instance of the object, but rather a handle that operates on the
exact same object that was originally written.
Ok, as you can see, there are some special objects that are not being copyed during unparceling. But this is still a bit confusing. Does it mean we have another strong reference to the original object which prevents its garbage collection? And what are the use-cases for such objects?
To answer the aforementioned questions I decided to look through the Android source code. The methods I was looking for are readStrongBinder and writeStrongBinder which according to the docs do not cause a new object creation when the parcels are sent/received. And I think I found the desired answer in the ResultReceiver.java class. Here is the interesting line:
mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
To understand what is this line actually doing we should go to the official AIDL documentation. Here are the most important parts:
The steps a calling class must take to call a remote interface defined
with AIDL:
...
5. In your implementation of onServiceConnected(), you will receive an
IBinder instance (called service). Call
YourInterfaceName.Stub.asInterface((IBinder)service) to cast the
returned parameter to YourInterface type.
A few comments on calling an IPC service:
Objects are reference counted across processes.
So let's put all things together:
The parcelled objects can be extracted without involving deep copy process.
If the parcelled objects are read using readStrongBinder method no new instances are being created. We just objtain a new reference to the original object and this reference can prevent its dealllocation.
To know whether our object will be deep copyed after the parcel has been received we should take a closer look at the concrete Parcelable interface implementation.
Android documentation can be really confusing and it may take a lot of time to understand it correctly.
Hope this info will help you.
If you want to read about a real-world example when the confusion regarding Parcelable objects can cause serious problems check out my blog post.
I want to test some method, for example:
public class testObj {
..
public void upload(Context context, Data data, Info info, Listener listener, Bla bla, ....) {
...
}
}
now in some cases i just want to know that this method was called, but i do not care about anyy of the arguments passed.
Now calling Mockito.any(Foo.class) is very discouraging, I know i can also use matchers but it's not that great also.
Is there some cleaner way to achive this?
No; verify needs to identify the method you're referring to, which means you'll need to call the correct method signature. Keeping an actual method call will also allow IDEs and automated refactoring tools to search for and modify the calls appropriately.
If you're running your tests from a Java 8 source environment, you can use any() with no argument; Java 8 has improved the ability to infer generic types when given as a parameter.
Though it usually makes more sense just to use matchers and explicit calls, you do have a few similar capabilities:
For stubbing, you can sometimes use a default answer to avoid specifying a lot of redundant calls and method values, but that won't help you with verification.
For verification, you can use MockingDetails.getInvocations() to inspect calls without using the built-in Mockito capabilities.
PowerMockito has private method verification by name, but not the same for public methods.
The documentation states that
all non-primitive parameters require a directional tag indicating which way the data goes; and
primitives are in by default, and cannot be otherwise.
Then they proceed with giving an example where a String is missing the directional tag. Can a String be out or inout in Android AIDL?
Since strings are immutable I'd have to do an assignment on the method handling the call in order to change the string, something like myString = "hello to you too";. I know that in a regular method this argument myString would remain unchanged at the caller side. Is that behavior applied here?
I wanted to know what is the inout param in the AIDL is for?
I know what is in for and what out is for. (out does not marshal the object passing).
But I don't understand what is the inout for.
I have looked in the:
"In/out/inout" in a AIDL interface parameter value?
question but still did not understand.
From my testings the param is passed much like specifying it as in.
So if any1 can shed some light on what is inout It would be helpful.
Thanks
An in parameter is only transported from the caller to the callee. An out parameter is transported from the callee to the caller. And an inout parameter is transported both ways.
You would use an inout paramter when you pass an object to the callee and the callee changes it.
Here it my version of explaining the directional tags in AIDL,
Its only a directional tag indicating which way the data goes.
in - object is transferred from client to service only used for
inputs
out - object is transferred from client to service only used
for outputs.
inout - object is transferred from client to service
used for both inputs and outputs.
All non-primitive parameters require a directional tag indicating which way the data goes. Either in, out, or inout.
Primitives are in by default, and cannot be otherwise
Please note, RPC calls from clients are synchronous.
You should limit the direction to what is truly needed, because marshaling parameters is expensive.
Example:
Please check the below AIDL interface to understand it in a better way.
package com.hardian.sample.aidl;
import com.hardian.sample.aidl.TeamMember;
interface ITeamManageService {
void getTeamCaptian(out TeamMember member);
void updateTeamMember(inout TeamMember member, in boolean isLeader);
oneway void removeTeamMember(in TeamMember member);
}
Here we have used out, in, inout directional tags to indicate which way the data goes.
getTeamCaptian(out TeamMember member) :
Get the captain of the team.
Here the "out" directional tag means, when the client calls this method, the "member" object has no relevant data,
but the server shall make changes to the "member" object, so the client shall get the updated "member" object.
In fact, the method call is synchronous.
updateTeamMember(inout TeamMember member, in boolean isLeader) :
Update the captian of the team.
Here the "inout" directional tag means, when the client calls this method,the "member" object has relevant data in it.
And the server shall use the input data and process it. Once the process completed, the client shall get the relevant data back.
In fact, the method call is synchronous.
removeTeamMember(in TeamMember member)
Remove a member from the team.
Here the "in" directional tag means, the "member" object is transferred from client to service only used for inputs.
If any changes are made to the "member" object in the service then it won’t reflect in the client.
The method call is asynchronous, we can put the "oneway" keyword to the method signature.
Asynchronous methods must not have "out" and "inout" arguments, they must also return void.