Как исправить ошибки в андроид студио

Время на прочтение
3 мин

Количество просмотров 59K

Сегодня хотел бы поделиться своим анализом и способами лечением разных ошибок при разработке своего продукта в Android Studio. Лично я, не раз сталкивался с различными проблемами и ошибками при компиляции и/или тестировании мобильного приложения. Данный процесс, всегда однообразный и в 99% случаев и всегда нужно тратить n-колличество времени на его устранение. Даже, когда ты уже сталкивался с данной проблемой, ты все равно идешь в поисковик и вспоминаешь, как же решить ту или иную ситуацию.

Я для себя завел файлик, в котором отметил самые частые ошибки — потратив на это несколько часов и перечислил самые популярные ошибки (в дальнейшем планирую просто их запомнить), чтоб сократить свое время в дальнейшем.

Итак, начну по порядку с самой распространенной проблемы и дальше буду перечислять их по мере появления:

1) Если подчеркивает красным код, где используются ресурсы: R. — попробовать (но вероятно не поможет): Build -> Clean Project.

В принципе на Build -> Clean Project можно не терять времени, а лучше всего — слева переключиться на Project, открыть каталог .idea, затем каталог libraries и из него удалить все содержимое. Затем нажать кнопку Sync Project. А затем (если все еще красное, но скорее всего уже будет все ок ) Build -> Clean Project.

image

2) После внезапного выключения компьютера, после перезапуска может быть во всех проектах весь код красным. Перед этим может быть ошибка: Unable to create Debug Bridge: Unable to start adb server: Unable to obtain result of ‘adb version’. Есть три решения — первое помогло, второе нет (но может быть для другого случая), а третье — не пробовал:

а) File — Invalidate Caches/Restart — Invalidate and Restart

б) Закрыть студию. В корне папки проекта удалить файл(ы) .iml и папку .idea. Вновь запустить студию и импортировать проект.

в) Нажать Ctrl-Alt-O и запустить оптимизацию импорта.

Кстати, adb сервер можно проверить на версию (и работоспособность) и затем перезапустить:

adb version
adb kill-server
adb start-server

3) Если Android Studio выдает приблизительно такую ошибку: Error:Execution failed for task ‘:app:dexDebug’…

Решение:

Надо слева переключиться на опцию Project, найти и удалить папку build которая лежит в папке app, т.е. по пути app/build. Затем перестроить весь проект заново: Build -> Rebuild Project.

Такое же решение если ошибка типа: «не могу удалить (создать) папку или файл» и указан путь, который в ведет в app/build. Тоже удаляем папку build и ребилдим проект.

4) В сообщении об ошибке упоминается heap — виртуальная память. А ошибка обычно вызвана ее нехваткой, т.е. невозможностью получить запрашиваемый объем. Поэтому этот запрашиваемый объем надо уменьшить, т.е. переписать дефолтное значение (обычно 2048 MB которое можно изменить в настройках), на меньшее 1024 MB.

В файле проекта gradle.properties пишем:

org.gradle.jvmargs=-Xmx1024m

5) Android Studio пришет примерно такую ошибку: Plugin is too old, please update to a more recent version, or set ANDROID_DAILY_OVERRIDE environment variable to «83648b99316049d63656d7276cb19cc7e95d70a5»

Возможные причины (кроме необходимости регулярного обновления SDK):

а) Загруженный проект был скомпилирован с помощью уже несовместимого старого gradle плагина. В этом случае надо найти и подключить в своем build.gradle проекта этот более старый плагин. т.е. попробовать более старые версии, например: 1.1.3 (часто именно 1.1.x и подходит).

com.android.tools.build:gradle:1.1.3

Найти все версии можно здесь.

б) Если в build.gradle проекта используется beta-версия плагина — это означает, что срок ее истек. Посмотреть последние релизы (продакшн и бета) можно также здесь:

6) Иногда при подключении сторонних библиотек могут дублироваться некоторые файлы (обычно связанные с лицензированием). В сообщении будет что-то содержащее слова: duplicate files. Решение — надо посмотреть в сообщении об ошибке или в документации подключенной сторонней библиотеки — какие именно файлы стали избыточными, и перечислить их в build.gradle модуля для исключения (exclude) из билда.

Это делается в директиве packagingOptions (которая, в свою очередь, находится в директиве android).

Например, при подключении библиотеки Firebase (облачный бек-енд сервис) в случае возникновения такой ошибки в build.gradle модуля (не проекта) добавляем packagingOptions в android (уже существующие там директивы оставляем) так:

android {
    ...
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE-FIREBASE.txt'
        exclude 'META-INF/NOTICE'
        }
}

P.S.: Думаю, данная статья была полезна. Если у вас есть еще какие-то частные проблемы при работе с проектами в Android Studio, с удовольствием выслушаю их. Как по мне, 6 проблемных причин, которые я перечислил выше — это 99% всех случаев краха проекта. Конечно, если проблема не связана с вашим личным кодом.

While developing applications in Android Studio we might encounter many errors while writing code in the editor. We know that there’s an error since the editor automatically detects in real-time and highlights it in red color like this

Well, in the above image we can see that the error occurs due to a closing bracket after orderLists in Line 58. We can say that because the editor detects that in real-time and warns us with red underlining at that line. Now we can write error-less code and our app should run, right? Well, NO. Because the editor only helps in detecting the syntax error in the code. Whereas we have many other kinds of errors that might cause our app not to work the way we want it to be. Runtime and Logical errors are the common ones and cannot be detected in the editor. 

Now the question is – We have written 100’s and 1000’s lines of error less codes or I should syntax error free code that compiles and runs without any problem. But my app still stops working or some features don’t work the way I want it to?

In this situation, the Logcat acts as our best friend. Logcat Window is the place where various messages can be printed when an application runs. Suppose, you are running your application and the program crashes, unfortunately. Then, Logcat Window is going to help you to debug the output by collecting and viewing all the messages that your emulator throws. So, this is a very useful component for the app development because this Logcat dumps a lot of system messages and these messages are actually thrown by the emulator. In Android Studio one of the most used tools is Logcat. Logcat window in Android Studio is used to display real-time system messages and messages that are added in the Log class of the app. To open Logcat Click View > Tool Windows > Logcat (Alt + 6 or from the toolbar window).

Most Common Types of Error

  • NullPointerException – When expecting from null variables, objects, or classes.
  • IOException – Exceptions produced by failed or interrupted I/O operations.
  • OutOfMemoryError – When an object cannot be allocated more memory by its garbage collector.

Solutions to fix App Crash 

1. Observe the App Crash

Suppose you have built an application with multiple activities or fragments or both then you need to observe and see which action causes the application to crash. This might sometimes help you automatically remember or recall what mistake was made and which part of the app is causing that.

2. Find the Stack Trace 

It is best to look at the logcat to find the exact point of error. You can open the logcat and in the error section start reading the log error messages. Scroll to the bottom of the screen and look for the line that says Caused by. You may find the file name and line number in the logcat messages, which will lead you directly to the cause of the error. Look for elements to resolve the error. 

  • File Name
  • Line Number
  • Exception Type
  • Exception Message

3. Investigation Techniques

There are times when you might not find the exact line of code or file name that’s causing the error. So you should following techniques to investigate by yourself – 

  • Toast – Toast messages are used to display alerts messages and in this case, you can use them to display failure messages.
  • Logging – Logging is used to print messages in the logcat.
  • Breakpoints – It can be used to investigate values at the points where breaks are applied.

4. Google for Solution

There will be times we cannot fix the bug by ourselves and that’s ok. That’s the time you should start searching for solutions on the internet. Try googling with the main query message like – java.lang.NullPointerException. Generally, try looking for links of StackOverflow with maximum matching keywords of your search in the google search results. Afterward, you can go for other portals if you do not find the solution in StackOverflow.

Last Updated :
30 Jun, 2021

Like Article

Save Article

Testing is a crucial part of Android development, allowing you to iron out all the bugs, errors and performance problems that may be lurking in your app, before you unleash it on the general public.

Every time you encounter an error, Android generates an error message, and then either displays that message as part of Android Studio’s Logcat Monitor or as a dialogue on the device you’re using to test your app.

These error messages are typically short and to the point, and at first glance may not seem all that helpful. However, these messages actually contain all the information you need to get your project back on track—you just need to know how to decipher them!

In this article, we’re going to take an in-depth look at the 13 error messages you’re most likely to encounter when developing any Android app. We’ll be scrutinising what each of these error messages really means, examining all the possible reasons why you might encounter each error and, most importantly, sharing step-by-step instructions on how you can resolve them.  

Spotting Error Messages

There’s a wide range of error messages you may encounter when testing your app, ranging from severe errors that will cause your app to crash the very first time you try to install it on a target device to more subtle errors that degrade your application’s performance over time.

Depending on the kind of error you encounter, Android will display the error message either on the device you’re using to test your app or in Android Studio.

Spotting error messages that appear on a physical device or AVD is easy—you just need to be paying attention to any dialogues that appear on your device’s screen! However, spotting errors that appear in Android Studio can be tricky, as the Logcat Monitor records a huge amount of information, making it easy to miss important error messages. 

The easiest way to make sure you don’t miss out any error messages is to open Logcat Monitor’s Verbose dropdown and set it to Error, which will filter out everything except error messages.

Open Logcat Monitors dropdown and select ErrorOpen Logcat Monitors dropdown and select ErrorOpen Logcat Monitors dropdown and select Error

1. R.layout.main Cannot Be Found / Cannot Resolve Symbol R

This error is caused when Android Studio can’t generate your R.java file correctly, and it can often crop up out of nowhere—one minute everything will be working fine, and the next minute every part of your project is failing to compile. To make matters worse, when Android Studio encounters the R.layout error, it’ll usually flag all your layout resource files as containing errors, which makes it difficult to know where to start looking for the source of the error.

Often, the most effective solution is the simplest: clean and rebuild your project. Select Build > Clean Project from the Android Studio toolbar, wait a few moments, and then build your project by selecting Build > Rebuild Project.

If a single clean/rebuild cycle doesn’t work, then try repeating this process a few times, as some developers have reported positive results after completing multiple clean/rebuild cycles in quick succession.

If you encounter this error after moving some files and directories around, then it’s possible that the R.layout error is being caused by a mismatch between Android Studio’s cache and your project’s current layout. If you suspect this may be the case, then select File > Invalidate Caches / Restart > Invalidate and Restart from Android Studio’s toolbar.

Issues with the names of your resources can also prevent the R.java file from being created correctly, so check that you don’t have multiple resources with the same name and that none of your file names contain invalid characters. Android Studio only supports lowercase a-z, 0-9, full stops and underscores, and a single invalid character can cause an R.layout error across your entire project, even if you don’t actually use this resource anywhere in your project!

If you do identify and resolve an error, but Android Studio is still displaying the R.layout error, then you may need to complete a clean/rebuild cycle before Android Studio properly registers your changes.

2. Too Many Field References….Max is 65,536

When you compile your app, the APK contains executable bytecode files in the form of Dalvik Executable (DEX) bytecode files. The DEX specification states that a single DEX file can reference a maximum of 65,536 methods, and if you encounter the Too many fields… error then it means your app has gone over this limit. Note that this is a limitation on the number of methods your project references, and not the number of methods your project defines.

If you encounter this error, then you can either:  

  • Reduce the number of references in your project. One of the most effective ways of trimming your method references is to review your application’s dependencies, as these are often one of the biggest contributors of method references.
  • Configure your app to use more than one DEX file, by enabling multidex.

The process of enabling multidex support will vary depending on the versions of Android your project supports.

If you’re targeting Android 5.0 or higher, then the first step is opening your module-level build.gradle file and setting multiDexEnabled to true:

1
android {
2
   defaultConfig {
3
       minSdkVersion 21
4
       multiDexEnabled true

However, if your minSdkVersion is 20 or lower, then you’ll need to add the multiDexEnabled true attribute and then add the multidex support library as a project dependency:

1
dependencies {
2
 compile 'com.android.support:multidex:1.0.1'
3
}

The next step depends on whether or not you’re overriding the Application class.

If your project does override the Application class, then open your Manifest and add the following to the <application> tag:

1
<application
2
           android:name="android.support.multidex.MultiDexApplication" >
3
       ...
4
       ...
5
       ...
6
   </application>

If your project doesn’t override the Application class, then you’ll need to extend MultiDexApplication instead:

1
public class MyApplication extends MultiDexApplication

Finally, if you do override the Application class but can’t change the base class, then you can enable multidex by overriding the attachBaseContext() method and calling MultiDex.install(this), for example:

1
@Override
2
 protected void attachBaseContext(Context base) {
3
    super.attachBaseContext(base);
4
    MultiDex.install(this);
5
 }

3. Please Choose a Valid JDK Directory

If you’re getting a JDK error whenever you try to build your app, then it means Android Studio is struggling to find where the JDK is installed on your development machine.

To fix this error:

  • Select File > Project structure… from the Android Studio toolbar.
  • Select SDK Location from the left-hand menu.
  • Make sure the Use embedded JDK checkbox is selected.

Navigate to File  Project structure  SDK Location and select the Use embedded JDK checkboxNavigate to File  Project structure  SDK Location and select the Use embedded JDK checkboxNavigate to File  Project structure  SDK Location and select the Use embedded JDK checkbox

If this doesn’t solve the problem, then navigate back to File > Project structure… > SDK Location, and manually enter the full file path for your JDK. If you’re not sure where the JDK is installed on your development machine, then you can find out by opening the Terminal (Mac) or Command Prompt (Windows) and entering the following command:

4. Error Installing APK

While AVDs are great for testing your app across a wide range of different hardware and software, you should always test your app on at least one physical Android smartphone or tablet. However, Android Studio’s ability to recognize a connected Android device is notoriously hit and miss.

If you’ve attached your device to your development machine but are encountering an Error installing APK message whenever you try to install your APK, or your device isn’t even appearing in the Select Deployment Target window, then try the following fixes:

Check USB debugging is enabled. 

Open your device’s Settings, then select Developer Options, and make sure USB Debugging is enabled. If you don’t see Developer Options in the Settings menu, then select About Phone and keep tapping Build Number until a You are now a developer notification appears. Return to the main Settings screen, and you should find that Developer Options has been added.

Check your smartphone or tablet’s screen. 

Sometimes your device may require some additional input before it connects to your development machine. For example, it may be asking you to choose between different modes, or to explicitly authorize the connection.

Make sure you have the correct USB driver installed. 

If you’re developing on Windows, then you’ll need to download the appropriate OEM USB driver for your device. If you’re a Nexus user, then you can download the Google USB driver through Android Studio’s SDK Manager.

Check that your device meets your project’s minimum SDK requirements. 

You’ll find your project’s minimum SDK in your module-level gradle.build file, and can check what version of Android is installed on your device by opening its Settings and swiping to the About Phone section.

Try restarting your adb (Android Debug Bridge) process. 

Open a Terminal or Command Prompt window, and then change directory (cd), so it’s pointing at your platform-tools window, for example:

1
cd /Users/Downloads/adt-bundle-mac/sdk/platform-tools

Then, terminate and restart the adb process by entering the following commands, one after the other:

Restart everything! 

If all else fails, then try disconnecting and then reconnecting your device, restarting your device, restarting Android Studio and, as an absolute last resort, restarting your development machine.

5. INSTALL_FAILED_INSUFFICIENT_STORAGE

If you encounter this error when attempting to install your project, then it means the target device doesn’t have enough memory.

If you’re trying to install your project on an AVD, then you should check how much space you’ve assigned this particular AVD:

  • Launch the AVD Manager.
  • Find the AVD in question, and click its accompanying Edit this AVD icon.
  • In the window that appears, click Show Advanced Settings.
  • Scroll to the Memory and Storage section.

This section lists the various types of memory you’ve allocated to this particular AVD. If any of these values are unusually low, then you should increase them to more closely reflect the memory that’s available to your typical Android smartphone or tablet:

  • RAM. The amount of RAM available to the emulated device.
  • VM Heap. How much heap space (i.e. memory) is allocated to the Virtual Machine (VM) of the emulated smartphone or tablet.
  • Internal Storage. The amount of non-removable memory available to the emulated device.
  • SD card. The amount of removable memory available. If you want to use a virtual SD card that’s managed by Android Studio, then select Studio-managed and enter the size of the virtual SD card you want to create (the minimum recommended value is 100 MB). Alternatively, you can manage the SD card “space” in a file, by selecting External file and then specifying the location you want to use.

If there’s nothing odd about your AVD’s memory, or you’re trying to install your app on a physical Android smartphone or tablet, then this error usually means that your compiled app is simply too large. An application that takes a significant bite out of the device’s memory at install time is never going to go down well. 

If you need to dramatically reduce the size of your APK, then try the following techniques: 

  • Use ProGuard to remove unused classes, fields, methods, and attributes. To enable ProGuard, open your module-level build.gradle file and add the following:

1
buildTypes {
2
      release {
3

4
//Enable ProGuard//
5

6
          minifyEnabled true
7

8
//Since we want to reduce our APK size as much as possible, I’m using the settings from the proguard-android-optimize.txt file//
9

10
          proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
11

12
      }
13
  }
14

15
}
  • Use the aapt tool to optimize your drawables with lossless compression, or use a program that’s designed to reduce the size of your PNG files (zopflipng, pngcrush, OptiPNG, TinyPNG, or pngquant) or the size of your JPEGs (packJPG). Alternatively,  you may want to try replacing your PNG and JPEG files with images in the WebP format.
  • Remember to remove all debug-related functionality from the release version of your app. Android doesn’t require this information to run, so it’s just taking up unnecessary space.
  • Scour your project for any duplicate resources. Even lightweight resources like duplicate strings contribute something towards your final APK size.
  • Use Lint to identify any resources that aren’t referenced anywhere in your code, and remove these resources. To run Lint, select Analyze > Inspect Code… from the Android Studio toolbar.
  • Enable resource shrinking, by adding shrinkResources true to your project’s build.gradle file.
  • If you need to use variations of the same image, then use the same base image and customize it at runtime, rather than adding multiple versions of the same image to your project. For example, you can apply different colours to an image using android:tint and tintMode, and you can rotate an image using android:fromDegrees, android:toDegrees, android:pivotX, and android:pivotY.
  • Optimize your libraries. Try to remove any unnecessary or memory-intensive libraries from your project. If you do need to use a large library, then check whether there’s any way you can optimize this library for the mobile environment, as external library code often isn’t written with mobile in mind. You should also bear in mind that many libraries contain a large amount of localized strings. If your app doesn’t officially support these libraries, then you may be able to reduce the size of the library by telling Gradle not to include these strings in your compiled APK. To specify the languages that your app officially supports, open your module-level build.gradle file and use the resConfigs attribute. For example, here we’re specifying that we want to include only English-language strings in our project:

1
android {
2
defaultConfig {
3
  resConfigs "en"
  • Consider whether your APK contains a large amount of content that the individual user may download but never use. For example, a device with an hdpi screen doesn’t have much use for xxxhdpi assets! One of the most effective ways of reducing the size of your APK is to separate it into multiple APKs, so when the user downloads your app, they’ll receive an APK that contains only the code and resources that make sense for their particular device. You’ll find more information on creating APKs that target different screen densities and specific ABIs (application binary interfaces) over at the official Android docs.

6. ActivityNotFoundException

An ActivityNotFoundException occurs when a call to startActivity(Intent) or one of its variants fails because the Activity can’t execute the given Intent.

The most common cause of an ActivityNotFoundException is forgetting to declare an activity in your manifest, so open your manifest and check that you’ve declared all your activities. You should also check that you’ve declared each activity correctly, using either a fully qualified class name or a full stop as a shorthand for the package name. For example, both of the following are valid:

1
<activity android:name=".MainActivity">
1
<activity android:name="com.jessicathornsby.myapplication.MainActivity">

If you can’t spot any problems with your manifest, then there are a few other potential causes of ActivityNotFoundExceptions. Firstly, if you encounter this error after moving an Activity class from one package to another, then it’s possible that you’ve confused Android Studio and just need to clean and rebuild your project.

An ActivityNotFoundException can also be caused if an error in the target Activity is not loading correctly. To check whether this is occurring in your project, put your intent code inside a try-catch block:

1
try {
2

3
//Your code here//

4

5
} catch ( ActivityNotFoundException e) {
6
      e.printStackTrace();
7

8
}

Run your application again, and then take a look at Android Studio’s Logcat Monitor to see whether it’s captured any exceptions that may be preventing the target activity from being created. If this is the case, then resolving these errors should solve the ActivityNotFoundException, too.

7. ClassCastException

The ClassCastException error is related to Java’s type conversion feature, which allows you to cast variables of one type to another. You encounter a ClassCastException when you try to cast an object to a class of which it’s not an instance. For example, both of the following code snippets will result in a ClassCastException:

1
Object x = new Integer(0);
2
System.out.println((String)x);
1
ImageView image = (ImageView)context.findViewById(R.id.button);

This error message contains information about the line that’s causing the ClassCastException error, so navigate to this part of your project, check what objects are being cast there, and resolve any mismatch.

If you can’t spot a problem with your casting, then consider whether you’ve recently moved some Views around in your layout resource files, as some users have reported encountering a ClassCastException after rearranging their Views. If you suspect this may be the cause of your ClassCastException, then tell Android Studio to regenerate your layout files from scratch, by performing a clean/rebuild cycle. This forces Android Studio to properly register your recent layout changes, which should resolve your ClassCastException.

8. NullPointerException

In Java, when you declare a reference variable, you’re actually creating a pointer to an object. You can declare that an object is currently pointing at an unknown piece of data by assigning a null value to that object’s reference. Null values can be useful in coding some design patterns, but if you encounter a NullPointerException (NPE) then it means that you’ve tried to use a reference that’s pointing at a null value, as though it were referencing an object. Since there’s no code to execute in the location where this reference is pointing, you wind up with an NPE.

An NPE is usually accompanied by information about where this exception was caught, so the Logcat Monitor should contain the exact line where this error occurred. Navigate to this area of your project and identify the reference that equals null. You’ll then need to find the location where the value should be set, and set it.

The findViewById method can also return null if the requested View can’t be found, so if your NPE is occurring in a line that contains a findViewById, check that you’ve initialized the layout that contains this View. Also be on the lookout for any spelling mistakes or typos that may have crept into your findViewById call, as these can also result in an NPE.  

To avoid NPEs occurring in your project, make sure all your objects are initialized before you attempt to use them, and always verify that a variable isn’t null before you request a method or field from that object.

9. Application Not Responding Error

This is an error that appears as a dialogue on the Android device or AVD you’re using to test your app. The Application Not Responding (ANR) error occurs when your app’s UI freezes and remains unresponsive to user input for more than five seconds. This usually happens because your app is trying to perform lengthy or intensive operations on Android’s main UI thread.

In Android, the main UI thread is responsible for dispatching all user input events to the appropriate UI widgets, and for updating your app’s UI. However, this thread can only process one task at a time, so if you block the main thread with any long-running or intensive operations, then your UI will be completely unresponsive until this task is complete.

If you encounter an ANR message while testing your app, then you definitely need to take a look at the work you’re performing on the main thread. However, if you don’t explicitly encounter this error but notice that your app sometimes feels sluggish or laggy, then this is an indication that you’re on the verge of an ANR error, and once again you should take a look at the state of your UI thread.

To resolve ANR errors (and near-ANR errors), you need to identify all the operations that have the potential to run slowly, or that require significant processing power, and then move them off the main thread. You do this by creating a worker thread where these operations can be performed with zero risk of blocking the main UI thread.

There are several methods of creating additional threads, but the simplest solution is to use an AsynTask, as this class already contains its own worker thread and an onPostExecute() callback that you can use to communicate with Android’s main UI thread.

However, AsyncTasks are better suited to performing short background operations, so if you need to perform a long-running operation, then you should use a Service or an IntentService instead.

Although moving long-running and intensive tasks off the main thread will have the most impact on your app’s performance, it’s best practice to perform as little work as possible on the main UI thread. Even running a small amount of unnecessary code on the main thread can have an impact on your app’s responsiveness, so once you’ve successfully relocated all of your long-running and intensive operations, you should look at whether there’s any more code that you can move off the main thread.

10. Only the Original Thread That Created a View Hierarchy Can Touch Its Views

In Android, you can update your UI from the main thread only. If you try to access UI elements from any other thread, then you’re going to encounter this error.

To resolve this issue, identify the part of your background task that’s attempting to update the UI and move it to a runOnUiThread, for example:

1
runOnUiThread(new Runnable() {
2
         @Override
3
          public void run() {
4

5
//Update your UI//

6

7
      }
8

9
});

Alternatively, you can use a handler or perform your background work in an AsyncTask, as you can communicate with the main thread using AsyncTask’s onPostExecute() callback method. Finally, if you find yourself regularly switching between threads, then you may want to look into RxAndroid, as this library allows you to create a new thread, schedule work to be performed on this thread, and then post the results to the main thread, all with just a few lines of code.

11. NetworkOnMainThreadException

This exception is thrown when your app attempts to perform networking operations on the main thread, such as sending API requests, connecting to a remote database, or downloading a file. Since network operations can be time-consuming and labour-intensive, they are highly likely to block the main thread, so Android 3.0 (Honeycomb) and higher will throw this error whenever you attempt to make a network request on the main thread.

If you do encounter a NetworkOnMainThreadException, then find the networking code that’s running on your main thread, and move it to a separate thread.

If you do need to make frequent networking requests, then you may want to take a look at Volley, an HTTP library that initiates its own background threads so that all networking requests are performed off the main thread by default.

12. Activity Has Leaked Window That Was Originally Added Here

This error occurs when trying to show a dialogue after exiting the Activity. If you do encounter this issue, then open your Activity and make sure you’re dismissing the dialogue properly, by calling dismiss() in either your Activity’s onDestroy() or onPause() method, for example:

1
@Override
2
protected void onDestroy()
3
{
4
       super.onDestroy();
5
        if(pDialogue!= null)
6
            pDialogue.dismiss();   
7
            
8
}

13. OutofMemoryError

This error occurs when your app makes a memory request that the system can’t meet. If you encounter this error message, then start by ruling out all of the most common memory management mistakes. Check that you’ve remembered to unregister all your broadcast receivers and that you’ve stopped all of your services; make sure you’re not holding onto references in any static member variables, and that you’re not attempting to load any large bitmaps.

If you’ve ruled out all the obvious causes of an OutOfMemoryError, then you’ll need to dig deeper and examine exactly how your app is allocating memory, as chances are there are a few areas where you can improve your app’s memory management.

Android Studio has a whole area dedicated to helping you analyze your app’s memory usage, so start by selecting View > Tools Window from the Android Studio toolbar. At this point you’ll see either an Android Monitor or Android Profiler option, depending on the version of Android Studio you have installed.

We’ve discussed working with the Memory Monitor on this website before, but since Android Profiler is a new addition to Android Studio, let’s take a quick look at its major features.

When you open Android Profiler, it starts recording three pieces of information automatically.

The Android Profiler tracks the apps CPU Memory and Network information automaticallyThe Android Profiler tracks the apps CPU Memory and Network information automaticallyThe Android Profiler tracks the apps CPU Memory and Network information automatically

Since we’re interested in the way our app is using memory, give the Memory section a click, which will launch the Memory Profiler.

The Memory Profiler consists of a timeline that displays the different kinds of memory currently being allocated by your app, for example Java, native, and stack. Above this graph you’ll find a row of icons that you can use to trigger different actions:

  • Force a garbage collection event.
  • Take an Hprof snapshot of the application memory. This is a snapshot of all the objects in your app’s heap, including the kind of objects your app is allocating, the number of allocated objects, and how much space these objects are taking up.
  • Record memory allocations. By recording your app’s memory allocations while performing certain actions, you can identify the specific operations that are consuming too much memory.

The Memory Profiler displays the different kinds of memory your app is allocating The Memory Profiler displays the different kinds of memory your app is allocating The Memory Profiler displays the different kinds of memory your app is allocating

To identify the parts of your application that are responsible for the OutOfMemoryError, spend some time interacting with your app, and monitor how your app’s memory allocations change in response to different actions. Once you’ve identified the section of your project that’s causing the problem, spend some time scrutinising it for any memory leaks, as well as any inefficiencies in the way it’s using memory.

Conclusion

In this article we looked at 13 of the error messages you’re most likely to encounter when developing for Android. We discussed all the different factors that can contribute towards these errors, and the steps you need to take to resolve them.

If you’re being plagued by an error message that we didn’t cover, then your first step should be copy/pasting the entire error message into Google, as this will often turn up threads and blog posts where people are discussing how to solve this particular error.

And, if you can’t find a solution anywhere on the web, then you can always reach out to the Android community for help directly, by posting your question to Stack Overflow.

While you’re here, check out some of our other posts on Android app development!

Did you find this post useful?

Jessica Thornsby

Jessica Thornsby is a technical writer based in Sheffield. She writes about Android, Eclipse, Java, and all things open source. She is the co-author of iWork: The Missing Manual, and the author of Android UI Design.

Приготовьте отладчик! Пишем приложение с ошибками, затем учимся их находить и дебажить

https://gbcdn.mrgcdn.ru/uploads/post/2735/og_image/ce05da5c8c8f97a3bf7713b7cbaf3802.png

Иногда в приложении встречаются ошибки, которые нельзя увидеть даже после запуска. Например, код компилируется, проект запускается, но результат далёк от желаемого: приложение падает или вдруг появляется какая-то ошибка (баг). В таких случаях приходится «запасаться логами», «брать в руки отладчик» и искать ошибки.

Часто процесс поиска и исправления бага состоит из трёх шагов:

  1. Воспроизведение ошибки — вы понимаете, какие действия нужно сделать в приложении, чтобы повторить ошибку.
  2. Поиск места ошибки — определяете класс и метод, в котором ошибка происходит.
  3. Исправление ошибки.

Если приложение не падает и чтение логов ничего не даёт, то найти точное место ошибки в коде помогает дебаггер (отладчик) — инструмент среды разработки.

    Чтобы посмотреть на логи и воспользоваться дебаггером, давайте напишем простое тестовое (и заведомо неправильное) приложение, которое даст нам все возможности для поиска ошибок.

    Это будет приложение, которое сравнивает два числа. Если числа равны, то будет выводиться результат «Равно», и наоборот. Начнём с простых шагов:

  1. Открываем Android Studio. 
  2. Создаём проект с шаблоном Empty Activity. 
  3. Выбираем язык Java, так как его, как правило, знают больше людей, чем Kotlin. 

Нам автоматически откроются две вкладки: activity_main.xml и MainActivity.java. Сначала нарисуем макет: просто замените всё, что есть в activity_main.xml, на код ниже:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">
 
  <EditText
     android:id="@+id/first_number_et"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:ems="10"
     android:gravity="center"
     app:layout_constraintLeft_toLeftOf="parent"
     app:layout_constraintRight_toRightOf="parent"
     app:layout_constraintTop_toTopOf="parent" />
 
  <EditText
     android:id="@+id/second_number_et"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:ems="10"
     android:gravity="center"
     app:layout_constraintLeft_toLeftOf="parent"
     app:layout_constraintRight_toRightOf="parent"
     app:layout_constraintTop_toBottomOf="@+id/first_number_et" />
 
  <Button
     android:id="@+id/button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="Равно?"
     app:layout_constraintLeft_toLeftOf="parent"
     app:layout_constraintRight_toRightOf="parent"
     app:layout_constraintTop_toBottomOf="@+id/second_number_et" />
 
  <TextView
     android:id="@+id/answer_tv"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text=""
     android:textSize="32sp"
     app:layout_constraintLeft_toLeftOf="parent"
     app:layout_constraintRight_toRightOf="parent"
     app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>

Можете запустить проект и посмотреть, что получилось:

Теперь оживим наше приложение. Скопируйте в MainActivity этот код:

public class MainActivity extends AppCompatActivity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
 
     final Button button = (Button) findViewById(R.id.button);
     final EditText first = (EditText) findViewById(R.id.first_number_et);
     final EditText second = (EditText) findViewById(R.id.second_number_et);
     final TextView answer = (TextView) findViewById(R.id.answer_tv);
 
     button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           Integer firstInt = Integer.parseInt(first.getText().toString());
           Integer secondInt = Integer.parseInt(second.getText().toString());
           if (firstInt == secondInt) {
              answer.setText("Равно");
           } else {
              answer.setText("Равно");
           }
        }
     });
  }
}

В этом коде всё просто: 

  1. Находим поля ввода, поле с текстом и кнопку.
  2. Вешаем на кнопку слушатель нажатий.
  3. По нажатию на кнопку получаем числа из полей ввода и сравниваем их.
  4. В зависимости от результата выводим «Равно» или «Не равно».

Запустим приложение и введём буквы вместо чисел:

Нажмём на кнопку, и приложение упадёт! Время читать логи. Открываем внизу слева вкладку «6: Logcat» и видим:

Читать логи просто: нужно найти красный текст и прочитать сообщение системы. В нашем случае это java.lang.NumberFormatException: For input string: «f». Указан тип ошибки NumberFormatException, который говорит, что возникла какая-то проблема с форматированием числа. И дополнение: For input string: «f». Введено “f”. Уже можно догадаться, что программа ждёт число, а мы передаём ей символ. Далее в красном тексте видно и ссылку на проблемную строку: at com.example.appdebugging.MainActivity$1.onClick(MainActivity.java:26). Проблема в методе onClick класса MainActivity, строка 24. Можно просто кликнуть по ссылке и перейти на указанную строку:

int firstInt = Integer.parseInt(first.getText().toString());

Конечно, метод parseInt может принимать только числовые значения, но никак не буквенные! Даже в его описании это сказано — и мы можем увидеть, какой тип ошибки этот метод выбрасывает (NumberFormatException).

Здесь мы привели один из примеров. Типов ошибок может быть огромное количество, все мы рассматривать не будем. Но все ошибки в Logcat’е указываются по похожему принципу: 

  • красный текст;
  • тип ошибки — в нашем случае это NumberFormatException;
  • пояснение — у нас это For input string: «f»;
  • ссылка на строку, на которой произошла ошибка — здесь видим MainActivity.java:26. 

Исправим эту ошибку и обезопасим себя от некорректного ввода. Добавим в наши поля ввода android:inputType=»number», а остальной код оставим без изменений:

...
<EditText
  android:id="@+id/first_number_et"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:ems="10"
  android:gravity="center"
  android:inputType="number"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toTopOf="parent" />
 
<EditText
  android:id="@+id/second_number_et"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:ems="10"
  android:gravity="center"
  android:inputType="number"
  app:layout_constraintLeft_toLeftOf="parent"
  app:layout_constraintRight_toRightOf="parent"
  app:layout_constraintTop_toBottomOf="@+id/first_number_et" />
...

    Теперь можем вводить только числа. Проверим, как работает равенство: введём одинаковые числа в оба поля. Всё в порядке:

На равенство проверили. Введём разные числа: 

Тоже равно. То есть приложение работает, ничего не падает, но результат не совсем тот, который требуется. Наверняка вы и без дебаггинга догадались, в чём ошибка, потому что приложение очень простое, всего несколько строк кода. Но такие же проблемы возникают в приложениях и на миллион строк. Поэтому пройдём по уже известным нам этапам дебаггинга:

  1. Воспроизведём ошибку: да, ошибка воспроизводится стабильно с любыми двумя разными числами.
  2. Подумаем, где может быть ошибка: наверняка там, где сравниваются числа. Туда и будем смотреть.
  3. Исправим ошибку: сначала найдём её с помощью дебаггера, а когда поймём, в чём проблема, — будем исправлять.

И здесь на помощь приходит отладчик. Для начала поставим точки останова сразу в трёх местах:

    Чтобы поставить или снять точку останова, достаточно кликнуть левой кнопкой мыши справа от номера строки или поставить курсор на нужную строку, а затем нажать CTRL+F8. Почему мы хотим остановить программу именно там? Чтобы посмотреть, правильные ли числа сравниваются, а затем определить, в какую ветку в нашем ветвлении заходит программа дальше. Запускаем программу с помощью сочетания клавиш SHIFT+F9 или нажимаем на кнопку с жучком:

  

    Появится дополнительное окно, в котором нужно выбрать ваш девайс и приложение:

Вы в режиме дебага. Обратите внимание на две вещи:

  1. Точки останова теперь помечены галочками. Это значит, что вы находитесь на экране, где стоят эти точки, и что дебаггер готов к работе.
  2. Открылось окно дебага внизу: вкладка «5: Debug». В нём будет отображаться необходимая вам информация.

    Введём неравные числа и нажмём кнопку «РАВНО?». Программа остановилась на первой точке:

Давайте разбираться:

  1. Сразу подсвечивается синим строка, где программа остановлена: в окне кода на 28-й строке и в левом окне отладчика (там даже можно увидеть, какой метод вызван, — onClick).
  2. В правом, основном окне отладчика, всё гораздо интереснее. Здесь можно увидеть инстансы наших вью (answer, first, second), в конце которых серым текстом даже отображаются их id. Но интереснее всего посмотреть на firstInt и secondInt. Там записаны значения, которые мы сейчас будем сравнивать.

Как видим, значения именно такие, какие мы и ввели. Значит, проблема не в получении чисел из полей. Давайте двигаться дальше — нам нужно посмотреть, в правильную ли ветку мы заходим. Для этого можно нажать F8 (перейти на следующую строку выполнения кода). А если следующая точка останова далеко или в другом классе, можно нажать F9 — программа просто возобновит работу и остановится на следующей точке. В интерфейсе эти кнопки находятся здесь:

Остановить дебаггер, если он больше не нужен, можно через CTRL+F2 или кнопку «Стоп»:

    В нашем случае неважно, какую кнопку нажимать (F9 или F8). Мы сразу переходим к следующей точке останова программы:

Ветка правильная, то есть логика программы верна, числа firstInt и secondInt не изменились. Зато мы сразу видим, что подпись некорректная! Вот в чём была ошибка. Исправим подпись и проверим программу ещё раз.

    Мы уже починили два бага: падение приложения с помощью логов и некорректную логику (с помощью отладчика). Хеппи пас (happy path) пройден. То есть основная функциональность при корректных данных работает. Но нам надо проверить не только хеппи пас — пользователь может ввести что угодно. И программа может нормально работать в большинстве случаев, но вести себя странно в специфических состояниях. Давайте введём числа побольше и посмотрим, что будет:

Не сработало — программа хочет сказать, что 1000 не равна 1000, но это абсурд. Запускаем приложение в режиме отладки. Точка останова уже есть. Смотрим в отладчик:

Числа одинаковые, что могло пойти не так? Обращаем внимание на тип переменной — Integer. Так вот в чём проблема! Это не примитивный тип данных, а ссылочный. Ссылочные типы нельзя сравнивать через ==, потому что будут сравниваться ссылки объектов, а не они сами. Но для Integer в Java есть нюанс: Integer может кешироваться до 127, и если мы вводим по единице в оба поля числа до 127, то фактически сравниваем просто int. А если вводим больше, то получаем два разных объекта. Адреса у объектов не совпадают, а именно так Java сравнивает их.

Есть два решения проблемы:

  1. Изменить тип Integer на примитив int.
  2. Сравнивать как объекты.

    Не рекомендуется менять тип этих полей в реальном приложении: числа могут приходить извне, и тип лучше оставлять прежним. Изменим то, как мы сравниваем числа:

if (firstInt.equals(secondInt)) {
  answer.setText("Равно");
} else {
  answer.setText("Не равно");
}

Проверяем:

Всё работает. Наконец-то! Хотя… Давайте посмотрим, что будет, если пользователь ничего не введёт, но нажмёт на кнопку? Приложение опять упало… Смотрим в логи:

Опять NumberFormatException, при этом строка пустая. Давайте поставим точку останова на 26-й строке и заглянем с помощью отладчика глубже.

Нажмём F8 — и перейдём в глубины операционной системы:

    Интересно! Давайте обернём код в try/catch и посмотрим ошибке в лицо. Если что, поправим приложение. Выделяем код внутри метода onClick() и нажимаем Ctrl+Alt+T:

Выбираем try / catch, среда разработки сама допишет код. Поставим точку останова. Получим:

Запускаем приложение и ловим ошибку:

Действительно, как и в логах, — NumberFormatException. Метод parseInt выбрасывает исключение, если в него передать пустую строку. Как обрабатывать такую проблему — решать исключительно вам. Два самых простых способа:

  1. Проверять получаемые строки first.getText().toString() и second.getText().toString() на пустые значения. И если хоть одно значение пустое — говорить об этом пользователю и не вызывать метод parseInt.
  2. Или использовать уже готовую конструкцию try / catch:

Теперь-то точно всё в порядке! Хотя профессиональным тестировщикам это приложение никто не отдавал: поищете ещё ошибки? :)

Возможные ошибки и их решение

Дата создания:
02.04.2015

Здесь собраны рецепты исправления ошибок, которые могут возникнуть при выполнении шагов из статей этой главы. В случае, если вашей ситуации здесь нет, отпишитесь, пожалуйста, в комментариях и я постараюсь помочь решить вам вашу проблему.

Если при ошибке выводится некая надпись, то её описание и решение будет находиться ниже под заголовком содержащим эту надпись.

Your project location contains non-ASCII characters. This can cause problems on Windows. Proceed with caution.

Предупреждение при создании проекта в Android Studio

Она появляется при создании нового проекта в Android Studio. Предупреждает о том, что путь к рабочей папке не валидный.

Решение

Выбрать путь к рабочей папке не содержащий кириллицу. Например, создать папку в корне диска D, чтобы путь был наподобие следующего D:Android

emulator: ERROR: x86 emulation currently requires hardware acceleration!

Полный текст:

>emulator: ERROR: x86 emulation currently requires hardware acceleration!
>Please ensure Intel HAXM is properly installed and usable.
>CPU acceleration status: HAX kernel module is not installed!.

Эта ошибка появляется при попытке запуска приложения на эмуляторе. Она означает, что не был установлен Intel Hardware Accelerated Execution Manager. Если интересно, вот здесь подробнее.

Решение

  1. Убедитесь в SDK Manager, что вы установили «Intel x86 Emulator Accelerator (HAXM installer)».

    SDK Manager Intel x86 Emulator Accelerator (HAXM installer)

    Установите в случае необходимости.

  2. Перейдите в директорию SDK (обычно это C:users{имя пользователя}AppDataLocalAndroidsdk), там перейдите в папку extrasintelHardware_Accelerated_Execution_Manager, там найдите файл intelhaxm-android.exe, запустите его и пройдите через мастер установки.

В случае если при установке вылетела ошибка «This computer meets requirements for HAXM, but VT-x is not turned on…»

Ошибка установки HAXM installer

То надо пойти в BIOS и включить Intel Virtual Technology.

Похожие статьи

Понравилась статья? Поделить с друзьями:
  • Как найти сиреноголового в гта 5
  • Как найти свое предназначение по дате рождения
  • Как найти силу тока через заряд электрона
  • Изумрудный парагон как найти
  • Как найти репетитора по итальянскому