क्या मैं Android उपकरणों पर मुखर का उपयोग कर सकता हूं?


88

मैं परीक्षण के दौरान एमुलेटर, या अपने डिवाइस पर कुछ मामलों में अपने ऐप को नष्ट करने के लिए अपने एंड्रॉइड ऐप में एस्सर कीवर्ड का उपयोग करना चाहता हूं । क्या यह संभव है?

ऐसा लगता है कि एमुलेटर सिर्फ मेरी बातों को नजरअंदाज करता है।


2
ART के लिए, Dalvik के बजाय, stackoverflow.com/questions/35997703/… पर
fadden

1
ध्यान दें कि स्वीकृत उत्तर काफी भ्रामक है।
गतिविधि

जवाबों:


-7

एपीआई JUnit मुखर प्रदान करता है ।

तुम कर सकते हो

import static junit.framework.Assert.*;

अब आप मुखर ढांचे में प्रदान किए गए सभी कार्यों जैसे कि मुखर, मुखर, मुखर का उपयोग कर सकते हैं।

ग्रहण के माध्यम से Junit4 ढांचे को आयात न करने के लिए सावधान रहें, यह org.junit पैकेज होगा। एंड्रॉइड डिवाइस या एमुलेटर पर काम करने के लिए आपको junit.framework पैकेज का उपयोग करना होगा।


51
खैर ओपी ने "मुखर खोजशब्द" के लिए कहा - जो कि junit.framework.Assert के विपरीत JIT द्वारा अनुकूलित किया जा सकता है। और इसी वजह से मैं यहां आया। आशा है कि कुछ अन्य उत्तर अधिक सहायक होंगे।
मार्टिन

27
मैं असभ्य होने से नफरत करता हूं, लेकिन यह स्वीकृत उत्तर नहीं होना चाहिए क्योंकि यह सवाल का जवाब नहीं देता है (मैं @Martin की टिप्पणी से सहमत हूं)। अन्य उत्तर बताते हैं कि एसेर कीवर्ड फ़ंक्शन को ठीक से कैसे बनाया जाए, उदाहरण के लिए "adb shell setprop debug.assert 1"
jfritz42

3
डाउनवोट किया गया क्योंकि ओपी ने मुखर कीवर्ड के बारे में पूछा। @scorpiodawg ने नीचे उल्लिखित प्रक्रिया दी है: stackoverflow.com/a/5563637/484261

scorpiodawg का उत्तर केवल एक साल बाद आया था, इसलिए मुझे लगता है कि यह उत्तर केवल इसलिए स्वीकार किया गया क्योंकि ओपी, किसी कारण से, एक उत्तर को चिह्नित करने के लिए बाध्य महसूस किया। यह रवैया एसओ पर जवाबों की एक बड़ी संख्या को अपूर्ण या एकमुश्त भयानक बनाता है।
async

145

एंबेडेड VM नियंत्रण दस्तावेज़ देखें ( स्रोत ट्री से कच्चा HTML , या एक अच्छी तरह से स्वरूपित प्रतिलिपि)।

मूल रूप से, Dalvik VM डिफ़ॉल्ट रूप से दावे की जाँच को अनदेखा करने के लिए सेट किया गया है, भले ही .dex बाइट कोड में चेक को करने के लिए कोड शामिल हो। दो तरीकों में से एक में जाँच की जाती है:

(1) सिस्टम प्रॉपर्टी को "debug.assert" द्वारा सेट करके:

adb shell setprop debug.assert 1

जो मैंने सत्यापित किया है कि जब तक आप यह करने के बाद अपने ऐप को पुन: स्थापित करते हैं, या तब तक काम करता है

(2) dalvik VM को कमांड लाइन तर्क "--enable-assert" भेजकर जो कि कुछ ऐप डेवलपर्स नहीं हो सकता है, ऐसा करने में सक्षम होने की संभावना है (कोई मुझे सही कर रहा है अगर मैं यहां गलत हूं)।

मूल रूप से, एक झंडा होता है जिसे या तो वैश्विक स्तर पर, एक पैकेज स्तर पर या एक वर्ग स्तर पर सेट किया जा सकता है जो उस संबंधित स्तर पर जोर देता है। ध्वज डिफ़ॉल्ट रूप से बंद है, जिसके परिणामस्वरूप अभिकथन चेक छोड़ दिया जाता है।

मैंने अपनी नमूना गतिविधि में निम्नलिखित कोड लिखा है:


public class AssertActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    int x = 2 + 3;
    assert x == 4;
  }
}

इस कोड के लिए, उत्पन्न होने वाली dalvik बाइट कोड (Android 2.3.3 के लिए) है:


// Static constructor for the class
000318:                                        |[000318] com.example.asserttest.AssertActivity.:()V
000328: 1c00 0300                              |0000: const-class v0, Lcom/example/asserttest/AssertActivity; // class@0003
00032c: 6e10 0c00 0000                         |0002: invoke-virtual {v0}, Ljava/lang/Class;.desiredAssertionStatus:()Z // method@000c
000332: 0a00                                   |0005: move-result v0
000334: 3900 0600                              |0006: if-nez v0, 000c // +0006
000338: 1210                                   |0008: const/4 v0, #int 1 // #1
00033a: 6a00 0000                              |0009: sput-boolean v0, Lcom/example/asserttest/AssertActivity;.$assertionsDisabled:Z // field@0000
00033e: 0e00                                   |000b: return-void
000340: 1200                                   |000c: const/4 v0, #int 0 // #0
000342: 28fc                                   |000d: goto 0009 // -0004

: :

// onCreate() 00035c: |[00035c] com.example.asserttest.AssertActivity.onCreate:(Landroid/os/Bundle;)V 00036c: 6f20 0100 3200 |0000: invoke-super {v2, v3}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method@0001 000372: 1501 037f |0003: const/high16 v1, #int 2130903040 // #7f03 000376: 6e20 0500 1200 |0005: invoke-virtual {v2, v1}, Lcom/example/asserttest/AssertActivity;.setContentView:(I)V // method@0005 00037c: 1250 |0008: const/4 v0, #int 5 // #5 00037e: 6301 0000 |0009: sget-boolean v1, Lcom/example/asserttest/AssertActivity;.$assertionsDisabled:Z // field@0000 000382: 3901 0b00 |000b: if-nez v1, 0016 // +000b 000386: 1251 |000d: const/4 v1, #int 5 // #5 000388: 3210 0800 |000e: if-eq v0, v1, 0016 // +0008 00038c: 2201 0c00 |0010: new-instance v1, Ljava/lang/AssertionError; // class@000c 000390: 7010 0b00 0100 |0012: invoke-direct {v1}, Ljava/lang/AssertionError;.:()V // method@000b 000396: 2701 |0015: throw v1 000398: 0e00 |0016: return-void

ध्यान दें कि स्टैटिक कंस्ट्रक्टर क्लास ऑब्जेक्ट पर वांछित वांछित डेटा को कैसे जमा करता है और क्लास-वाइड वैरिएबल $ assertionsDisabled सेट करता है; यह भी ध्यान दें कि onCreate () में, सभी कोड java.lang.AssertionError को फेंकने के लिए संकलित किया गया है, लेकिन इसका निष्पादन $ assertionsDisabled के मूल्य पर आकस्मिक है जो स्थिर निर्माण में क्लास ऑब्जेक्ट के लिए निर्धारित है।

ऐसा प्रतीत होता है कि JUnit का Assert वर्ग वह है जो मुख्य रूप से उपयोग किया जाता है, इसलिए इसका उपयोग करने के लिए एक सुरक्षित शर्त होने की संभावना है। मुखर खोजशब्द का लचीलापन विकास के समय में अभिकर्मकों को चालू करने और उन्हें शिपिंग बिट्स के लिए बंद करने की क्षमता है और इसके बजाय शालीनता से विफल हो जाते हैं।

उम्मीद है की यह मदद करेगा।


ऐसा प्रतीत होता है कि Google ने ब्राउज़ करने योग्य स्रोत को हटा दिया है (मैंने अन्य प्रश्नों के उत्तर में इसके संदर्भ देखें)। आपकी सबसे अच्छी शर्त या तो स्रोत प्राप्त करना है, या किसी खोज इंजन में इसे देखने का प्रयास करना है। "Dalvik / एम्बेडेड-vm-control.html" के लिए खोजें। यहाँ एक जगह है जो इसके पास है: असेंबली . com / code / android-gb-for-sharp-is01 / git / nodes / dalvik/… । उम्मीद है की यह मदद करेगा।
स्कॉर्पियोडावेग

बहुत उपयोगी है, धन्यवाद। मैं हालांकि दूसरे-से-अंतिम पैराग्राफ में किए गए भेद से भ्रमित हूं। हम दो प्रकार के सिद्धांतों पर चर्चा कर रहे हैं: पहला JUnit Assert पैकेज की विधियां जैसे assertNotNull (), और दूसरा जावा भाषा का 'मुखर' कीवर्ड है। क्या आपका जवाब दोनों पर लागू होता है? उदाहरण के लिए, अगर मैं import static junit.framework.Assert.*और फिर मैं इसके किसी एक तरीके का उपयोग करता हूं, जैसे assertNotNull("It's null!", someObject);, क्या यह दावा शिपिंग बिट्स में बंद हो गया है?
जेफ्रो

1
हाय जेफ़रो, मैं ऐसा नहीं मानता - junit.framework.Assert बस एक वर्ग है जो एक अपवाद फेंकता है जब इनपुट स्थिति झूठी पाई जाती है। दूसरी ओर मुखर खोजशब्द भाषा में बनाया गया है। उम्मीद है की यह मदद करेगा।
स्कॉर्पियोडावेग

3
क्या adb shell setprop debug.assert 1ग्रहण करने का कोई तरीका है ?
पचेरियर

1
यदि आप रूट हैं तो डिवाइस पर चल रहे टर्मिनल से भी दावे किए जा सकते हैं। पहले su, फिर setprop debug.assert 1। ध्यान दें कि जो कोड आपको असंतुष्ट दिखाते हैं, वह रिलीज़ बिल्ड ( stackoverflow.com/a/5590378/50907373 ) पर रहेगा । मुझे विश्वास नहीं है कि जेवैक कंपाइलर को कथनों का उत्सर्जन नहीं करने के लिए कहा जा सकता है, इसलिए उन्हें किसी तरह छीनने की जरूरत है। इसका एक सरल उपाय यह है कि आप अपने स्वयं के फंक्शन में कीवर्ड अस्सेर को लपेटें जो कि आपके लिए प्रागार्ड स्ट्रिप कर सकता है।
१०:५० पर आहॉक्स

10

जब दावे सक्षम होते हैं, तो बूलियन अभिव्यक्ति होने पर assertकीवर्ड बस फेंकता AssertionErrorहै false

तो IMO, सबसे अच्छा विकल्प, esp। यदि आप कनिष्ठ पर निर्भर होना चाहते हैं, तो AssertionErrorनीचे दिखाए अनुसार स्पष्ट रूप से फेंकना है :

assert x == 0 : "x = " + x;

उपरोक्त कथन का एक विकल्प है:

Utils._assert(x == 0, "x = " + x);

जहां विधि को इस प्रकार परिभाषित किया गया है:

public static void _assert(boolean condition, String message) {
    if (!condition) {
        throw new AssertionError(message);
    }
}

Oracle जावा डॉक्स स्वीकार्य विकल्प के रूप में फेंकने की सलाह देते हैंAssertionError

मुझे लगता है कि आप प्रोडक्शन कोड के लिए इन कॉल्स को हटाने के लिए Proguard को कॉन्फ़िगर कर सकते हैं।


लेकिन आप दावे कैसे सक्षम करते हैं? Android स्टूडियो पर?
SMBiggs

8

"एंड्रॉइड इन प्रैक्टिस" में इसका उपयोग करने का सुझाव दिया गया है:

$adb shell setprop dalvik.vm.enableassertions all

यदि यह सेटिंग आपके फ़ोन पर बनी नहीं है, तो आप /data/local.prop फ़ाइल को गुणों के साथ बना सकते हैं:

dalvik.vm.enableassertions=all

प्रति stackoverflow.com/a/18556839/2004714 पर , आपको यह भी सुनिश्चित करना होगा कि फ़ाइल केवल-पढ़ने के लिए बनाई गई है ( chmod 644)।
पाउलो

5

यह मेरे लिए नरक को कम कर रहा था, कि मेरे दावे ने काम नहीं किया, जब तक कि मैंने Google पर इस मुद्दे की जांच नहीं की ... मैंने सरल अभिकथन पर ध्यान दिया और जूनियर तरीकों के साथ जाना होगा।

सुविधा प्रयोजनों के लिए मैं उपयोग कर रहा हूँ:

स्थैतिक junit.framework.Assert। * आयात करें;

स्थिर आयात के कारण मैं बाद में लिख सकता हूं:

assertTrue (...); इसके बजाय Assert.assertTrue (...);


4

यदि आप (या किसी अन्य वर्ग पथ) में JUnit के साथ शिपिंग कोड के बारे में चिंतित हैं, तो आप ProGuard कॉन्फिगर विकल्प 'ग्रहण' का उपयोग कर सकते हैं, जो इस धारणा पर एक क्लास का रास्ता निकाल देगा कि यह कोड को कुछ भी नहीं करता है। ।

उदाहरण के लिए।

-assumenosideeffects junit.framework.Assert {
*;
}

मेरे पास एक सामान्य डीबग लाइब्रेरी है मैंने अपने सभी परीक्षण तरीकों को रखा, और फिर अपने जारी किए गए एप्लिकेशन से इसे हटाने के लिए इस विकल्प का उपयोग करें।

यह स्ट्रिंग्स के हेरफेर की समस्या को भी दूर करता है, जिसे रिलीज कोड में कभी इस्तेमाल नहीं किया जाता है। उदाहरण के लिए यदि आप एक डीबग लॉग विधि लिखते हैं, और उस विधि में आप स्ट्रिंग लॉग करने से पहले डीबग मोड की जाँच करते हैं, तो आप अभी भी स्ट्रिंग का निर्माण कर रहे हैं, मेमोरी आवंटित कर रहे हैं, विधि को कॉल कर रहे हैं, लेकिन फिर कुछ भी नहीं करने का विरोध कर रहे हैं। क्लास को स्ट्रिप करना फिर कॉल को पूरी तरह से हटा देता है, मतलब जब तक आपका स्ट्रिंग मेथड कॉल के अंदर निर्मित नहीं हो जाता है, तब तक यह चला जाता है।

सुनिश्चित करें कि यह वास्तव में सिर्फ लाइनों को बाहर निकालने के लिए सुरक्षित है, क्योंकि यह प्रोगार्ड के हिस्से पर कोई जाँच नहीं है। किसी भी शून्य वापसी विधि को हटाना ठीक होगा, हालाँकि यदि आप जो भी हटा रहे हैं, उससे कोई वापसी मान ले रहे हैं, तो सुनिश्चित करें कि आप वास्तविक परिचालन तर्क के लिए उनका उपयोग नहीं कर रहे हैं।


1
मुझे लगता है कि उचित वाक्यविन्यास होगा:-assumenosideeffects class junit.framework.Assert { *; }
Pooks

भ्रामक उत्तर। उल्लेखित कमांड त्रुटि का कारण बनता है। Pooks द्वारा ठीक की गई कमांड अभी भी बाइनरी डेक्स फ़ाइल से अभिक्रियाओं को नहीं हटाती है।
सूचक नल

मेरे पास एक ही समस्या है @PointerNull। मुखर अभ्यस्त हटा दिया।
महदी

3

आप अभिकथन का उपयोग कर सकते हैं, लेकिन उन्हें मज़बूती से उपयोग करने के लिए कुछ काम लगते हैं। सिस्टम की संपत्ति debug.assertअविश्वसनीय है; 175697 , 65183 , 36786 और 17324 मुद्दे देखें ।

एक विधि यह है assertकि किसी भी क्रम से निपटने के लिए प्रत्येक कथन का अनुवाद किया जाए। जावा कंपाइलर के सामने एक स्रोत प्रीप्रोसेसर के साथ ऐसा करें। उदाहरण के लिए, इस कथन को लें:

assert x == 0: "Failure message";

डीबग बिल्ड के लिए, आपका प्रीप्रोसेसर किसी ifकथन के लिए उपरोक्त का अनुवाद करेगा :

{ if( !(x == 0) ) throw new AssertionError( "Failure message" ); }

एक निर्माण के लिए, एक खाली बयान के लिए:

;

ध्यान दें कि यह निर्माण समय पर जोर को नियंत्रित करेगा, जैसा कि समय चलाने (सामान्य अभ्यास) के विपरीत है।

मुझे कोई रेडीमेड प्रीप्रोसेसर नहीं मिला, इसलिए मैंने एक स्क्रिप्ट की । दावे के साथ काम करने वाले भाग को देखें। कॉपी करने का लाइसेंस यहाँ है


1

जुगिटिया को जुनीत को बाहर करने के जवाब में जोड़ने के लिए - प्रोगार्ड पहले से ही एंड्रॉइड एसडीके / एक्लिप्स का हिस्सा है और निम्न पृष्ठ आपको बताता है कि इसे कैसे सक्षम किया जाए।

http://developer.android.com/guide/developing/tools/proguard.html

इसके अलावा उपरोक्त अभ्यस्त नवीनतम डिफ़ॉल्ट गार्ड विन्यास के साथ काम करता है क्योंकि यह -dontoptimize ध्वज का उपयोग करता है जिसे बाहर ले जाना चाहिए और कुछ अनुकूलन चालू हो गए।


0

उदाहरण के लिए, मानक जावा मुखर खोजशब्द का प्रयोग करें :

assert a==b;

इस काम के लिए, आपको /system/build.prop, और रिबूट फोन में एक पंक्ति जोड़ना होगा:

debug.assert=1

यह रूट किए गए फोन पर काम करेगा। Build.prop (जैसे X-plore) को संपादित करने में सक्षम कुछ फ़ाइल प्रबंधक का उपयोग करें।

प्लसस: अधिकांश (सभी?) एंड्रॉइड फोन जहाज के साथ अक्षम हैं। यहां तक ​​कि अगर आपका कोड गलती से झूठे का दावा करता है, तो ऐप बाधित या दुर्घटना नहीं करेगा। हालाँकि, आपके विकास उपकरण पर आपको अभिकथन अपवाद मिलेगा।

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