Android
अपवाद
खोज…
NetworkOnMainThreadException
जब कोई अनुप्रयोग अपने मुख्य थ्रेड पर नेटवर्किंग कार्रवाई करने का प्रयास करता है, तो अपवाद को फेंक दिया जाता है।
यह केवल हनीकॉम्ब एसडीके या उच्चतर को लक्षित करने वाले अनुप्रयोगों के लिए फेंका गया है। पहले एसडीके संस्करणों को लक्षित करने वाले अनुप्रयोगों को अपने मुख्य ईवेंट लूप थ्रेड्स पर नेटवर्किंग करने की अनुमति है, लेकिन यह बहुत हतोत्साहित है।
यहाँ एक कोड टुकड़ा का एक उदाहरण है जो उस अपवाद का कारण हो सकता है:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Uri.Builder builder = new Uri.Builder().scheme("http").authority("www.google.com");
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
URL url;
try {
url = new URL(builder.build().toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
} catch (IOException e) {
Log.e("TAG","Connection error", e);
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("TAG", "Error closing stream", e);
}
}
}
}
}
उपरोक्त कोड हनीकॉम्ब एसडीके (एंड्रॉइड v3.0) या उससे अधिक के अनुप्रयोगों के लिए NetworkOnMainThreadException
को फेंक NetworkOnMainThreadException
क्योंकि एप्लिकेशन मुख्य थ्रेड पर नेटवर्क ऑपरेशन करने की कोशिश कर रहा है।
इस अपवाद से बचने के लिए, आपके नेटवर्क संचालन को हमेशा एक AsyncTask
, Thread
, IntentService
, आदि के माध्यम से एक पृष्ठभूमि कार्य में चलना चाहिए।
private class MyAsyncTask extends AsyncTask<String, Integer, Void> {
@Override
protected Void doInBackground(String[] params) {
Uri.Builder builder = new Uri.Builder().scheme("http").authority("www.google.com");
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
URL url;
try {
url = new URL(builder.build().toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
} catch (IOException e) {
Log.e("TAG","Connection error", e);
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("TAG", "Error closing stream", e);
}
}
}
return null;
}
}
ActivityNotFoundException
यह एक बहुत ही सामान्य Exception
। यह आपके एप्लिकेशन को आपके ऐप की शुरुआत या निष्पादन के दौरान रोक देता है। LogCat
आप संदेश देखते हैं:
android.content.ActivityNotFoundException : Unable to find explicit activity class;
have you declared this activity in your AndroidManifest.xml?
इस मामले में, जांचें कि क्या आपने AndroidManifest.xml
फ़ाइल में अपनी गतिविधि घोषित की है।
AndroidManifest.xml
में अपनी Activity
घोषित करने का सबसे सरल तरीका है:
<activity android:name="com.yourdomain.YourStoppedActivity" />
बाहर स्मृति त्रुटि
यह एक रनटाइम त्रुटि है जो तब होता है जब आप ढेर पर बड़ी मात्रा में मेमोरी का अनुरोध करते हैं। बिटमैप को किसी इमेज व्यू में लोड करते समय यह आम है।
आपके पास कुछ विकल्प हैं:
- एक बड़े एप्लिकेशन हीप का उपयोग करें
अपने AndroidManifest.xml में एप्लिकेशन टैग में "bigHeap" विकल्प जोड़ें। यह आपके ऐप को अधिक मेमोरी उपलब्ध कराएगा लेकिन रूट समस्या को ठीक नहीं करेगा।
<application largeHeap="true" ... >
- अपने बिटमैप को रीसायकल करें
बिटमैप लोड करने के बाद, इसे रीसायकल करना और मेमोरी खाली करना सुनिश्चित करें:
if (bitmap != null && !bitmap.isRecycled())
bitmap.recycle();
- मेमोरी में सैंपल किए गए बिटमैप को लोड करें
एक छोटे आकार में एक बार पूरे बिटमैप को लोड करने से बचें, एक छोटे आकार का नमूना करके, BitmapOptions और InSampleSize का उपयोग करके।
उदाहरण के लिए Android प्रलेखन देखें
DexException
com.android.dex.DexException: Multiple dex files define Lcom/example/lib/Class;
यह त्रुटि इसलिए होती है क्योंकि ऐप, जब पैकेजिंग करता है, तो दो .dex
फाइलें ढूंढता है जो समान विधियों के सेट को परिभाषित करती हैं।
आमतौर पर ऐसा होता है क्योंकि ऐप ने गलती से एक ही लाइब्रेरी पर 2 अलग-अलग निर्भरता हासिल कर ली है।
उदाहरण के लिए, मान लें कि आपके पास एक परियोजना है, और आप दो पुस्तकालयों पर भरोसा करना चाहते हैं: A
और B
, जिनमें से प्रत्येक की अपनी निर्भरता है। यदि लाइब्रेरी B
पहले से ही लाइब्रेरी A
पर निर्भरता है, तो लाइब्रेरी A
को प्रोजेक्ट द्वारा स्वयं में जोड़े जाने पर यह त्रुटि हो जाएगी। संकलित पुस्तकालय B
ने पहले से ही A
से कोड का सेट दिया है, इसलिए जब कंपाइलर पुस्तकालय A
को बंडल करने के लिए जाता है, तो यह लाइब्रेरी A
के तरीकों को पहले से ही पैक करता है।
हल करने के लिए, सुनिश्चित करें कि आपकी कोई भी निर्भरता गलती से इस तरह से दो बार नहीं जोड़ी जा सकती है
पकड़ा ना गया अपवाद
यदि आप बिना किसी अपवाद को हैंडल करना चाहते हैं, तो आप उन सभी को पकड़ने की कोशिश करें, जो आप पर हैं।
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
Thread
.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
Log.e(TAG,
"Uncaught Exception thread: "+thread.getName()+"
"+e.getStackTrace());
handleUncaughtException (thread, e);
}
});
} catch (SecurityException e) {
Log.e(TAG,
"Could not set the Default Uncaught Exception Handler:"
+e.getStackTrace());
}
}
private void handleUncaughtException (Thread thread, Throwable e){
Log.e(TAG, "uncaughtException:");
e.printStackTrace();
}
}
अप्रत्याशित अपवादों के लिए खुद के हैंडलर को पंजीकृत करना
यह आप अपवादों पर प्रतिक्रिया कर सकते हैं जिन्हें पकड़ा नहीं गया है, सिस्टम के मानक के समान "एप्लीकेशन एक्सवाईजेड ने पकड़ा है"
import android.app.Application;
import android.util.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Application class writing unexpected exceptions to a crash file before crashing.
*/
public class MyApplication extends Application {
private static final String TAG = "ExceptionHandler";
@Override
public void onCreate() {
super.onCreate();
// Setup handler for uncaught exceptions.
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
try {
handleUncaughtException(e);
System.exit(1);
} catch (Throwable e2) {
Log.e(TAG, "Exception in custom exception handler", e2);
defaultHandler.uncaughtException(thread, e);
}
}
});
}
private void handleUncaughtException(Throwable e) throws IOException {
Log.e(TAG, "Uncaught exception logged to local file", e);
// Create a new unique file
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US);
String timestamp;
File file = null;
while (file == null || file.exists()) {
timestamp = dateFormat.format(new Date());
file = new File(getFilesDir(), "crashLog_" + timestamp + ".txt");
}
Log.i(TAG, "Trying to create log file " + file.getPath());
file.createNewFile();
// Write the stacktrace to the file
FileWriter writer = null;
try {
writer = new FileWriter(file, true);
for (StackTraceElement element : e.getStackTrace()) {
writer.write(element.toString());
}
} finally {
if (writer != null) writer.close();
}
// You can (and probably should) also display a dialog to notify the user
}
}
फिर अपने AndroidManifest.xml में इस एप्लिकेशन क्लास को पंजीकृत करें:
<application android:name="de.ioxp.arkmobile.MyApplication" >