10

OK, perhaps it is very simple, but I just can not figure it out right now.

I have imported google sample project Card Reader in Android Studio 1.5.1, it compiles at compileSdkVerison 23, it works on my Mobile.

Then I walked through the SDK while came to source code to android.nfc.tech.BasicTagTechnology, I found TransceiveResult inside android.nfc.tech.BasicTagTechnology#transceive couldn't not be resolved then I found the class TransceiveResult is missing in my D:\Android\sdk\platforms\android-23\android.jar, but presents in Android source code here D:\Android\sdk\sources\android-23\android\nfc\TransceiveResult.java then I realized it could be hidden from public, not exported, actually it is

/**
 * Class used to pipe transceive result from the NFC service.
 *
 * @hide
 */

public final class TransceiveResult implements Parcelable

Then I have done some random things, after I have sync the project, clean and rebuild, invalidate caches / restarted, still not able to resolve TransceiveResult by the way, I am wondering since the symbol has been lost in SDK, how can the project compile smoothly?

EDIT for I finally Aha

We call android.nfc.tech.BasicTagTechnology#transceive in our code rather than TransceiveResult, in the compile-time we no need to resolve TransceiveResult, we only need to resolve android.nfc.tech.BasicTagTechnology#transceive which is referenced in our code, I was lost at that moment.

http8086
  • 1,306
  • 16
  • 37
  • I don't quite get your question. Where does card reader sample app makes reference to `TransceiveResult`? – ozbek Apr 07 '16 at 02:57
  • @ozbek it was inside android.nfc.tech.BasicTagTechnology#transceive – http8086 Apr 07 '16 at 10:21
  • OK, but how is `android.nfc.tech.BasicTagTechnology` related to card reader sample app? – ozbek Apr 07 '16 at 10:24
  • @ozbek The transceive method was referenced in CardReader project – http8086 Apr 07 '16 at 10:27
  • OK. Then my original question still stands: _Where does card reader sample app makes reference to `TransceiveResult`?_ – ozbek Apr 07 '16 at 10:32
  • @ozbek Oh it is indirect, did I hear you were saying indirect reference does not count? – http8086 Apr 07 '16 at 10:35
  • 1
    Well, `@hide` means the class or method is hidden from the public (e.g., SDK or card reader app), but it'd still be accessible for the platform or within the same package. – ozbek Apr 07 '16 at 10:41

1 Answers1

7

@hide means its not included in the docs as described here and it is also stripped from the classes within your android.jar which is used in compilation. These however are available in runtime.

Update: To clarify in your IDE when you dig into your SDK classes you might see references to hidden members which you cannot resolve. This is OK and it will still compile as long as those are in the SDK classes not in your code.

If you want to use those hidden classes/methods/fields you have 2 main options:

1) fetch a full version of android-framework.jar and be able to compile. this however has a drawback that the compiled code will probably not run in other Android versions as the Class or the method might not be even there. and also BasicTagTechnology for example is actually package private so you cannot access it like that anyway

2) use reflection:

Class tr = Class.forName("android.nfc.TransceiveResult");
        Constructor constructor =
                tr.getConstructor(new Class[]{int.class, byte[].class});
        Object trObj = constructor.newInstance(1, new byte[]{1,2});

this is a better option in the sense that it is more flexible and you can check if the class/method exists to init/call them, catch exception etc.

kalin
  • 3,546
  • 2
  • 25
  • 31
  • It should be `tr.getConstructor(int.class, byte[].class)`, not `tr.getConstructor(new Class[]{int.class, byte[].class})` – Jared Rummler Apr 07 '16 at 22:32
  • they both work :) http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html – kalin Apr 07 '16 at 22:45
  • Good to know, my bad. :) – Jared Rummler Apr 07 '16 at 23:02
  • My question is how it can be compiled, not how to use hidden class in our code, actually I know how to use, directly or by reflection. However in the conversation we have, you have inspired me, made me realized that the symbol can not be resolved in SDK is OK, it was not in our code where something can not be resolved, thank you, would you like to edit your answer and then I can accept it – http8086 Apr 11 '16 at 11:16