जावा 7 भाषा एंड्रॉइड के साथ है


188

बस सोच रहा था कि क्या किसी ने एंड्रॉइड के साथ नए जावा 7 भाषा सुविधाओं का उपयोग करने की कोशिश की है? मुझे पता है कि एंड्रॉइड उस बाईटेकोड को पढ़ता है जिसे जावा बाहर निकालता है और इसे डीएक्स में बदल देता है। तो मुझे लगता है कि मेरा सवाल यह है कि क्या यह जावा 7 के बाईटेकोड को समझ सकता है?


10
वैकल्पिक रूप से, शायद आप जावा 7 भाषा सुविधाओं का उपयोग कर सकते हैं, लेकिन जावा 6 बायटेकोड पर संकलित कर सकते हैं?
मेट्रिक्सफ्रॉग

2
Android Studio अब आपको एक नया प्रोजेक्ट बनाते समय एक सूचना देगा: "minSdkVersion 19 से कम होने पर, आप कोशिश-के-संसाधनों का उपयोग नहीं कर सकते, लेकिन अन्य जावा 7 भाषा सुविधाएँ ठीक हैं"
IgGanapolsky

1
हाँ, मुझे पता है :) हम अंततः अपने प्रोजेक्ट में जावा 7 का उपयोग कर रहे हैं।
डैनियल रयान

जवाबों:


165

यदि आप एंड्रॉइड स्टूडियो का उपयोग कर रहे हैं , तो जावा 7 भाषा को बिना किसी पैच के अपने आप सक्षम होना चाहिए। कोशिश के साथ संसाधन के लिए एपीआई स्तर 19+ की आवश्यकता होती है, और एनआईओ 2.0 सामान गायब हैं।

यदि आप Java 7 सुविधाओं का उपयोग नहीं कर सकते हैं, तो अपने संपादन को कैसे संपादित करें, इस पर @ नूनो का उत्तर देखेंbuild.gradle

निम्नलिखित केवल ऐतिहासिक हित के लिए है।


जावा 7 का एक छोटा हिस्सा निश्चित रूप से एंड्रॉइड के साथ उपयोग किया जा सकता है (ध्यान दें: मैंने केवल 4.1 पर परीक्षण किया है)।

सबसे पहले, आप ग्रहण के एडीटी का उपयोग नहीं कर सकते क्योंकि यह हार्ड-कोडेड है कि केवल जावा कंपाइलर 1.5 और 1.6 कंपाउंडेंट हैं। आप ADT को फिर से जोड़ सकते हैं, लेकिन मुझे लगता है कि ऐसा करने का कोई सरल तरीका नहीं है कि एक साथ पूरे एंड्रॉइड को एक साथ फिर से स्थापित करने से अलग किया जाए।

लेकिन आपको ग्रहण का उपयोग करने की आवश्यकता नहीं है। उदाहरण के लिए, Android Studio 0.3.2 , IntelliJ IDEA CE और अन्य javac- आधारित IDEs Android को संकलित करने का समर्थन करता है और आप इसके साथ Java 8 तक का अनुपालन भी सेट कर सकते हैं:

  • फ़ाइल → प्रोजेक्ट संरचना → मॉड्यूल → (2 फलक पर मॉड्यूल उठाओ) → भाषा का स्तर → ("7.0 - हीरे, एआरएम, बहु-पकड़, आदि" चुनें)

IntelliJ पर जावा 7 को सक्षम करना

यह केवल जावा 7 भाषा सुविधाओं की अनुमति देता है , और आप कुछ भी से शायद ही लाभ उठा सकते हैं क्योंकि सुधार भी पुस्तकालय से आता है। आपके द्वारा उपयोग की जा सकने वाली विशेषताएँ वे हैं जो लाइब्रेरी पर निर्भर नहीं करती हैं:

  • हीरा ऑपरेटर ( <>)
  • स्ट्रिंग स्विच
  • एकाधिक-पकड़ ( catch (Exc1 | Exc2 e))
  • संख्याओं में अंडरस्कोर ( 1_234_567)
  • द्विआधारी शाब्दिक ( 0b1110111)

और इन सुविधाओं का उपयोग अभी तक नहीं किया जा सकता है :

  • try-साथ-संसाधनों बयान - क्योंकि यह गैर मौजूदा इंटरफेस "java.lang.AutoCloseable" की आवश्यकता है (इस 4.4+ में सार्वजनिक रूप से इस्तेमाल किया जा सकता)
  • @SafeVarargs एनोटेशन - क्योंकि "java.lang.SafeVarargs" मौजूद नहीं है

... "अभी तक" :) यह पता चला है कि, हालांकि एंड्रॉयड के पुस्तकालय 1.6 के लिए लक्षित कर रहा है, एंड्रॉयड स्रोत की तरह इंटरफेस शामिल करता है AutoCloseable और पारंपरिक इंटरफेस की तरह closeable AutoCloseable से विरासत करता है (SafeVarargs वास्तव में याद आ रही है, हालांकि)। हम प्रतिबिंब के माध्यम से इसके अस्तित्व की पुष्टि कर सकते हैं। वे केवल इसलिए छिपे हुए हैं क्योंकि जावदोक में @hideटैग है, जो "android.jar" को उन्हें शामिल नहीं करने का कारण बना।

पहले से ही मौजूदा प्रश्न के रूप में है कि मैं छिपे हुए और आंतरिक एपीआई के साथ एंड्रॉइड एसडीके कैसे बनाऊं? कैसे उन तरीकों को वापस पाने के लिए। आपको बस प्रतिस्थापित करने की आवश्यकता है हमारे अनुकूलित एक के साथ मौजूदा प्लेटफ़ॉर्म के मौजूदा "android.jar" संदर्भ की , फिर जावा 7 एपीआई के कई उपलब्ध हो जाएंगे (यह प्रक्रिया ग्रहण के समान है। परियोजना संरचना की जांच करें → एसडीके।)

AutoCloseable के अतिरिक्त, (केवल) निम्नलिखित जावा 7 लाइब्रेरी सुविधाएँ भी सामने आई हैं:

  • कॉन्ट्रासेन्ट मैडिफिकेशन एक्ससेप्शन, लिंकेजएयर और एश्योरियन एरर में एक्सेप्शन चाइनिंग कंस्ट्रक्टर्स
  • आदिम के लिए स्थिर .compare () विधियाँ: Boolean.compare (), Byte.compare (), Short.compare (), Character.compare (), Integer.compare (), Long.compare ()।
  • मुद्रा : .getAvailableCurrencies (), .getDisplayName () (लेकिन बिना .getNumericCode () के)
  • BitSet : .prepretSetBit (), .prepretClearBit (), .valueOO (), .toLongArray (), .toByteArray ()
  • संग्रह : .emptyEnumeration (), .emptyIterator (), .emptyListIterator ()
  • AutoCloseable
  • फेंकने योग्य : .adduppressed (), .getSuppressed (), और 4-तर्क निर्माता
  • चरित्र : .compare (), .isSurrogate (), .getName (), .highSurrogate (), .lowSurrogate (), .isBmpCodePoint () (लेकिन बिना .isAlphabetic () और .isIdeographic ()) के।
  • सिस्टम: .lineSeparator ()
  • java.lang.reflect.Modifier : .classModifiers (), .constructorModifiers (), (.fieldModifiers) (), .interfaceModifiers (), .methodModifiers ()।
  • NetworkInterface : .getIndex (), .getByIndex ()
  • InetSocketAddress : .getHostString ()
  • InetAddress : .getLoopbackAddress ()
  • लकड़हारा : .getGlobal ()
  • ConcurrentLinkedDeque
  • AbstractQueuedSynchronizer : .QQueduedPredwardors ()
  • DeflaterOutputStream : "syncFlush" के साथ 3 कंस्ट्रक्टर्स।
  • Deflater : .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate (4 तर्क के साथ)

यह मूल रूप से सभी है। विशेष रूप से, NIO 2.0 मौजूद नहीं है, और Arrays.asList अभी भी @SafeVarargs नहीं है।


2
बहुत बढ़िया जवाब। मुझे उम्मीद है कि भविष्य में पूरी jvm स्तर का समर्थन जल्द ही होगा, nio2और अन्य उपहार निश्चित रूप से एक अच्छी खबर होगी।
एसडी

4
AutoCloseableआईसीएस (या शायद हनीकॉम्ब तक) एंड्रॉइड रनटाइम में उस इंटरफ़ेस का उल्लेख करने के लिए मौजूद नहीं है। यदि आप android.jar पैच का उपयोग करते हैं तो भी आप NoClassDefFoundError2.x प्रणाली पर प्राप्त करेंगे ।
आइडलोन

2
@deviant: इसके लिए Dalvik VM को संशोधित करने की आवश्यकता है, क्योंकि Java 8 lambda का उपयोग करता है invokedynamicजो कि JVM लक्ष्य जावा 6. द्वारा समर्थित नहीं है
kennytm

2
आप एक अपडेट जोड़ना चाह सकते हैं कि Android Studio 3.2 के रूप में, भाषा स्तर 7 पूरी तरह से समर्थित है, जैसा कि आप किटकैट
JRaymond

4
संसाधनों के साथ प्रयास अब एसडीके 19 (एंड्रॉइड किटकैट) पर उपयोग किया जा सकता है। उपकरण देखें ।android.com
मोहम्मद अल-

70

EDIT: जिस समय यह लिखा गया था, उस समय नवीनतम रिलीज़ Android 9 और ग्रहण इंडिगो थी। तब से थिंकिंग बदल गई है।

  • व्यावहारिक उत्तर

हां, मैंने कोशिश की है। लेकिन यह एक महान परीक्षण नहीं है क्योंकि संगतता 6 स्तर तक सीमित थी (कोई सरल तरीका कम से कम) वास्तव में जावा 7 का उपयोग करने के लिए:

  • पहले मैंने एक JDK7 को एक ऐसी मशीन पर स्थापित किया था जिसमें कोई अन्य JDK स्थापित नहीं था - ग्रहण और Android या तो स्थापित नहीं होते हैं:

इस मशीन पर 7 ही स्थापित है

  • तब मैंने एक नया ग्रहण इंडिगो स्थापित किया और जाँच की कि यह वास्तव में जेडीके 7 का उपयोग कर रहा है (ठीक है, क्योंकि यह केवल एक है और जैसा कि मैंने चुना है, मुझे आश्चर्य होगा)

इस ग्रहण द्वारा केवल 7 का उपयोग किया जाता है

  • तब मैंने Android SDK (EDIT: Honeycomb, API13 का नवीनतम संस्करण स्थापित किया था, उस समय यह पोस्ट लिखी गई थी)। यह मेरा JDK 7 पाया और ठीक से स्थापित किया। ADT के लिए भी यही।

  • लेकिन मुझे एक आश्चर्य हुआ जब एक हैलो वर्ड एंड्रॉइड ऐप को संकलित करने और चलाने की कोशिश की गई थी। संगतता को जावा 6 के लिए सेट किया गया था, जिससे उसे जावा 7 पर मजबूर करने का कोई तरीका नहीं था:

संगतता जावा 6 तक सीमित है

  • मैंने एक गैर-एंड्रॉइड प्रोजेक्ट, एक नियमित जावा एक के साथ कोशिश की, और मेरे पास स्पष्टीकरण था। संगतता स्तर ग्रहण द्वारा सीमित प्रतीत होता है (निम्न छवि के नीचे संदेश देखें):

ग्रहण स्वयं को 6 अनुकूलता तक सीमित करता है

इसलिए मैं था नमस्ते विश्व काम कर रहे हैं, और भी अन्य एप्लिकेशन, और अधिक जटिल और का उपयोग कर SQLite, Listview, SensorऔरCamera , लेकिन यह केवल साबित होता है कि अनुकूलता जावा 7 की हैंडलिंग अच्छी तरह से किया और Android के साथ काम कर रहा है।

तो, क्या किसी ने अच्छी पुरानी चींटी के साथ कोशिश की, ऊपर दिखाई गई ग्रहण सीमा को बायपास करने के लिए?

  • थिरकने वाला जवाब

वैसे भी, एसडीके को जावा 5 या 6 के साथ उपयोग करने के लिए डिज़ाइन किया गया है, जैसा कि यहां बताया गया है

हमारे पास जावा 7 के साथ कुछ काम हो सकता है, लेकिन यह "दुर्घटना से" काम करेगा। DEX की बिल्डिंग ठीक से काम कर सकती है या नहीं, और DEX के बन जाने के बाद यह काम कर सकती है या नहीं। ऐसा इसलिए है क्योंकि गैर-योग्य JDK का उपयोग परिभाषा द्वारा अप्रत्याशित परिणाम देता है।

यहां तक ​​कि अगर किसी ने सादे जावा 7 के तहत एक Android एप्लिकेशन बनाया है, तो यह JDK योग्य नहीं है। किसी अन्य एप्लिकेशन पर लागू की गई समान प्रक्रिया विफल हो सकती है, या परिणामी एप्लिकेशन में उस JDK के उपयोग के लिए बग हो सकते हैं। सिफारिश नहीं की गई।

उन लोगों के लिए जो वेबएप्स डेवलपमेंट से जुड़े हैं, यह बिल्कुल जावा 5 या 6 के तहत बनाए गए वेब एप्लिकेशन को लागू करने के समान है, जो केवल जावा 4 के लिए योग्य है (उदाहरण के लिए वेबलॉजिक 8 कहते हैं)। यह काम कर सकता है, लेकिन यह ऐसा कुछ नहीं है जिसे कोशिश करने के अलावा अन्य उद्देश्यों के लिए अनुशंसित किया जा सकता है।


1
उस विस्तृत समीक्षा के लिए धन्यवाद। ऐसा लगता है कि आप जावा 7 भाषा सुविधाओं का उपयोग नहीं कर सकते हैं, लेकिन फिर भी जावा 7 का जावा 6 के रूप में उपयोग करते हैं। उम्मीद है कि यह जल्द ही बदल जाएगा :)
डैनियल रयान

यह ग्रहण के साथ है। चींटी के साथ, यह संभव है। मुझे आशा है कि कोई व्यक्ति परीक्षण करेगा और मैं खुद को दोषी ठहराता हूं कि मैं ऐसा करने के लिए बहुत आलसी हूं :)
श्लूब्लू

हाँ वर्गा, लेकिन मुझे नहीं लगता कि संकलक संस्करण की सीमा चींटी से आती है लेकिन ग्रहण से।
शलुब्लू

2
यह भी ध्यान दें कि यदि आपके जावा के कई संस्करणों के साथ उपलब्ध कराए गए उपकरण संगत नहीं हैं। मेरा मतलब यह है कि अगर आपने पहले अपने ऐप को java 6 टूल्स से jarsigner के साथ साइन किया है और फिर बाद में java 7 स्थापित किया है और jarsigner के साथ हमारे ऐप के एक नए संस्करण पर हस्ताक्षर किए हैं जो java 7 और उसी kystore के साथ आए हैं, जैसा कि पहले हस्ताक्षर से मेल नहीं खाते होंगे; !
टिमो

38

Dalvikvm.com से उद्धरण:

dx, एंड्रॉइड SDK में शामिल है, नियमित रूप से जावा कंपाइलर द्वारा संकलित जावा कक्षाओं की जावा क्लास फाइलों को अन्य क्लास फाइल फॉर्मेट (.dex फॉर्मेट) में बदल देता है।

इसका मतलब है, .java स्रोत फ़ाइल कोई फर्क नहीं पड़ता, यह केवल .class bytecode है।

जहां तक ​​मुझे पता है, केवल जावा 7 में जेवीएम बायोटेक में केवल इनवॉइस डायनामिक जोड़ा गया था, बाकी जावा 6. के लिए संगत है। जावा भाषा में ही इनवॉकेन्डेमिक का उपयोग नहीं किया जाता है । अन्य नई सुविधाओं, जैसे स्विच कथन का उपयोग स्ट्रिंग या बहु पकड़ सिर्फ syntatic चीनी कर रहे हैं और बाइट कोड में परिवर्तन की आवश्यकता नहीं है। उदाहरण के लिए, बहु पकड़ने सिर्फ प्रतियां पकड़ प्रत्येक संभावित अपवाद के लिए -ब्लॉक की है।

एकमात्र समस्या यह होनी चाहिए कि जावा 7 में पेश की गई नई कक्षाएं एंड्रॉइड में ऑटोक्लोसेबल की तरह गायब हैं , इसलिए मुझे यकीन नहीं है कि आप कोशिश का उपयोग कर सकते हैं -साथ-संसाधनों की सुविधा (किसी इसे करने की कोशिश?)।

उस पर कोई टिप्पणी? क्या मैं कुछ भूल रहा हूँ?


2
अब समस्या यह है कि हम ऐसे कैसे कॉन्फ़िगर करें कि जावा 7 स्रोत कोड जावा 6 कक्षा की फाइलों को संकलित करते हैं, विशेष रूप से ग्रहण में?
रैंडी सुगियंटो 'युकू'

एक ही सवाल शेष है कि आप परेशान क्यों होंगे?
तानापिट

@Arpzit बड़ा सवाल यह होना चाहिए कि एक डेवलपर इस सारी उलझन के लिए परेशान क्यों नहीं होगा?
अमित

@Amit क्योंकि उसे एहसास है कि एंड्रॉइड जावा से अलग है और एंड्रॉइड के साथ काम करने के लिए उसे पेश किए जाने वाले टूल का उपयोग करना होगा।
वारपज़िट

2
@Arpzit उनका एकमात्र सवाल है " क्या एंड्रॉइड java 7 को समझ सकता है? " अज्ञानता कभी भी समाधान / उत्तर नहीं है ...
अमित

12

एंड्रॉइड एसडीके v15 के रूप में, ग्रहण 3.7.1 के साथ, जावा 7 एंड्रॉइड विकास के लिए समर्थित नहीं है । 1.7। उत्पन्न करने के लिए स्रोत संगतता सेट कर रहा है। 1.7 के लिए .class फ़ाइल संगतता सेट कर रहा है, जो Android कंपाइलर द्वारा निम्न त्रुटि की ओर जाता है:

Android को कंपाइलर कंप्लायंस लेवल 5.0 या 6.0 की आवश्यकता होती है। इसके बदले Found 1.7 ’मिला। कृपया Android उपकरण> प्रोजेक्ट गुण ठीक करें का उपयोग करें।


5

@KennyTM द्वारा उपरोक्त उत्तर पर विस्तार करने के लिए, यदि आप 4.0.3 और उससे अधिक का लक्ष्य कर रहे हैं ( minSdkVersion = 15) ) अपने लक्ष्य के एसडीके android.jar में कुछ कक्षाएं जोड़कर छिपे हुए एपीआई का उपयोग कर सकते हैं।

एक बार जब आप ऐसा कर लेते हैं, तो आप किसी भी क्लोजेबल पर ट्राय-विथ-रिसोर्स का उपयोग कर सकते हैं, साथ ही अपनी कक्षाओं में ऑटोक्लोसेबल को लागू कर सकते हैं।

मैंने उन सभी वर्गों के स्रोतों और बायनेरिज़ युक्त ज़िप बनाया है, जिन्हें इन एपीआई को उपलब्ध कराने के लिए android.jar में संशोधित करने की आवश्यकता है। आपको बस इसे अनपैक करने और अपने
android-sdk / platform / android-NN / android के लिए बायनेरिज़ जोड़ने की आवश्यकता है

आप इसे यहाँ से डाउनलोड कर सकते हैं: http://db.tt/kLxAYWbr

भी ध्यान रखने की है कि, महीने की पिछले कुछ में, इलियट ह्यूजेस एंड्रॉयड पेड़ करने के लिए कुछ करता बना दिया है: AutoCloseable बंद समाप्त हो गया , SafeVarargs जोड़ा , छिपे नहीं विभिन्न एपीआई , तय फेंकने योग्य की रक्षा की निर्माता और dx में संस्करण 51 वर्ग फ़ाइलों के लिए जोड़ा समर्थन । इसलिए, अंत में कुछ प्रगति हो रही है।

संपादित करें (अप्रैल 2014):

एसडीके 19 की रिहाई के साथ यह अतिरिक्त एपीआई के साथ android.jar पैच करने के लिए आवश्यक नहीं है।

एंड्रॉइड स्टूडियो में एंड्रॉइड स्टूडियो में कोशिश करने वाले संसाधनों का उपयोग करने का सबसे अच्छा तरीका जो कि 4.0.3 और उससे अधिक का लक्ष्य रखता है ( minSdkVersion = 15 ) निम्नलिखित compileOptionsको आपके साथ जोड़ रहा है build.gradle:

android {
    compileSdkVersion 19
    buildToolsVersion '19.0.3'

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 19
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

Android Studio शिकायत करेगा कि इस API स्तर के साथ try-with-resource का उपयोग नहीं किया जा सकता है, लेकिन मेरा अनुभव यह है कि यह हो सकता है। यह परियोजना 4.0.3 और इससे अधिक के उपकरणों पर समस्या के बिना बनाएगी और चलेगी। मैंने इसके साथ कोई समस्या नहीं अनुभव की है, एक ऐप के साथ जिसे 500k + डिवाइस में इंस्टॉल किया गया है।

Android स्टूडियो त्रुटि

इस चेतावनी को अनदेखा करने के लिए, निम्नलिखित को अपने में जोड़ें lint.xml:

<issue id="NewApi">
    <ignore regexp="Try-with-resources requires API level 19"/>
</issue>

1
मुझे यह दिलचस्प लगा कि एंड्रॉइड स्टूडियो कोड चेतावनी कहती है कि एपीआई 13 में प्रयास-के-संसाधन नए हैं और मुझे इसका उपयोग करना चाहिए। हालांकि यह सही ढंग से काम कर रहा है, तो वास्तव में परीक्षण करने का समय नहीं है।
डैनियल रयान

1

ऐसा लगता है कि यह शुद्ध चींटी के साथ काम करने के लिए मिल रहा है।

लेकिन इसने मेरे लिए काम किया: http://www.informit.com/articles/article.aspx?p=1966024


1
मैंने लंबे समय तक इसके लिए देखा। लेख के माध्यम से फ़िल्टरिंग के माध्यम से लोगों की परेशानी को काटने के लिए, आपको बिल्ड में उस `<प्रॉपर्टी का नाम =" java.source "मान =" 1.5 "/>` लाइन को बदलना होगा। जो कि android द्वारा प्रदान किया गया है। आपका प्रोजेक्ट!)। मेरे लिए यह /opt/android-sdk-update-manager/tools/ant/build.xml में था
Mateusz Kowalczyk

नहीं, तुम नहीं। आप उन गुणों को ओवरराइट कर सकते हैं custom_rules.xml, मेरा उत्तर यहां देखें: stackoverflow.com/a/24608415/194894
प्रवाह

1

एंड्रॉइड के चींटी आधारित निर्माण प्रणाली द्वारा कोड बिल्ड में जावा 7 सुविधाओं का उपयोग करने के लिए, बस custom_rules.xmlअपनी परियोजनाओं में रूट निर्देशिका में निम्नलिखित डालें :

custom_rules.xml:

<project name="custom_android_rules">
    <property name="java.target" value="1.7" />
    <property name="java.source" value="1.7" />
</project>

0

कुछ लोगों को इस git प्रोजेक्ट में रुचि हो सकती है जो मैंने पाया है, जो कि एंड्रॉइड पर जावा 7 चलाने की अनुमति देता है। https://github.com/yareally/Java7-on-Android

हालाँकि, यदि मैं वर्तमान परियोजना में काम करता हूं, तो मुझे इसमें बहुत अधिक जोखिम है। इसलिए मैं जावा 7 के आधिकारिक रूप से समर्थन करने के लिए Google की प्रतीक्षा करूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.