{"id":13522,"date":"2019-09-30T16:44:13","date_gmt":"2019-09-30T07:44:13","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=13522"},"modified":"2019-12-21T16:30:14","modified_gmt":"2019-12-21T07:30:14","slug":"%ec%95%88%eb%93%9c%eb%a1%9c%ec%9d%b4%eb%93%9c%ec%97%90%ec%84%9c-custom-lint-%ed%99%9c%ec%9a%a9%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=13522","title":{"rendered":"\uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Custom Lint \ud65c\uc6a9\ud558\uae30"},"content":{"rendered":"<h2>Lint\ub780?<\/h2>\n<p>Android \uc2a4\ud29c\ub514\uc624\uc5d0 \uc788\ub294 Lint\ub77c\ub294 \ucf54\ub4dc \uc2a4\uce94 \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud558\uba74 \uc571\uc744 \uc2e4\ud589\ud558\uac70\ub098 \ud14c\uc2a4\ud2b8 \uc0ac\ub840\ub97c \uc791\uc131\ud558\uc9c0 \uc54a\uace0\ub3c4 \ucf54\ub4dc\uc758 \uad6c\uc870\uc801 \ubb38\uc81c\ub97c \uc2dd\ubcc4\ud558\uace0 \uc218\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub3c4\uad6c\uc5d0\uc11c \ud0d0\uc9c0\ub41c \uac01 \ubb38\uc81c\ub294 \uc124\uba85 \uba54\uc2dc\uc9c0 \ubc0f \uc2ec\uac01\ub3c4 \uc218\uc900\uacfc \ud568\uaed8 \ubcf4\uace0\ub418\ubbc0\ub85c \uac1c\uc120\uc774 \uc2dc\uae09\ud55c \uc21c\uc11c\ub300\ub85c \uc2e0\uc18d\ud788 \uc6b0\uc120\uc21c\uc704\ub97c \uacb0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub610\ud55c \ud504\ub85c\uc81d\ud2b8\uc640 \uad00\ub828\uc774 \uc5c6\ub294 \ubb38\uc81c\ub97c \ubb34\uc2dc\ud574\uc11c \ubb38\uc81c\uc758 \uc2ec\uac01\ub3c4 \uc218\uc900\uc744 \ub0ae\ucd94\uac70\ub098 \ud2b9\uc815 \ubb38\uc81c\ub97c \uac15\uc870\ud558\uc5ec \uc2ec\uac01\ub3c4 \uc218\uc900\uc744 \ub192\uc77c \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Lint \ub3c4\uad6c\ub294 \uc7a0\uc7ac\uc801 \ubc84\uadf8\ub97c \ucc3e\uc544\ub0b4\uace0 \uc815\ud655\uc131, \ubcf4\uc548, \uc131\ub2a5, \uc0ac\uc6a9\uc131, \uc811\uadfc\uc131 \ubc0f \uad6d\uc81c\uc131\uc744 \ub192\uc774\uae30 \uc704\ud574 Android \ud504\ub85c\uc81d\ud2b8 \uc18c\uc2a4 \ud30c\uc77c\uc744 \uac80\uc0ac\ud569\ub2c8\ub2e4. Android \uc2a4\ud29c\ub514\uc624\ub97c \uc0ac\uc6a9\ud560 \uacbd\uc6b0 \uc571\uc744 \ube4c\ub4dc\ud560 \ub54c\ub9c8\ub2e4 \uad6c\uc131\ub41c Lint\uc640 IDE \uac80\uc0ac\uac00 \uc2e4\ud589\ub429\ub2c8\ub2e4. \ud558\uc9c0\ub9cc<span>\u00a0<\/span><a href=\"https:\/\/developer.android.com\/studio\/write\/lint?hl=ko#manuallyRunInspections\">\uac80\uc0ac\ub97c \uc218\ub3d9\uc73c\ub85c \uc2e4\ud589<\/a>\ud558\uac70\ub098<span>\u00a0<\/span><a href=\"https:\/\/developer.android.com\/studio\/write\/lint?hl=ko#commandline\">\uba85\ub839\uc904\uc5d0\uc11c Lint\ub97c \uc2e4\ud589<\/a>\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Lint\uac00 \ubc84\uadf8\ub97c \ucc3e\uae30 \uc704\ud55c \ucf54\ub4dc \ud0d0\uc0c9 \uc6cc\ud06c\ud50c\ub85c\ub294 \uc544\ub798\uc640 \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<p>&nbsp;<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/developer.android.com\/studio\/images\/write\/lint.png?hl=ko\" width=\"604\" height=\"287\" class=\"size-large aligncenter\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc \uc2a4\ud29c\ub514\uc624\uc758 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8\uc801\uc73c\ub85c \ud3ec\ud568\ub41c lint\uac00 \ud65c\uc131\ud654 \ub418\uc5b4\uc788\uae30 \ub54c\ubb38\uc5d0, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc0c1\ud669\uc5d0 \uc788\uc5b4\uc11c \uc624\ub958\ub97c \uac80\ucd9c\ud558\uace0 \uba54\uc2dc\uc9c0\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4. \uc608\ub97c\ub4e4\uc5b4 Toast \uac1d\uccb4\ub97c \ub9cc\ub4e4\uae30\ub9cc \ud558\uace0 show()\ub97c \ud638\ucd9c \ud558\uc9c0 \uc54a\uc544. \ud654\uba74\uc5d0 \ud1a0\uc2a4\ud2b8\uac00 \ub178\ucd9c\ub418\uc9c0 \uc54a\ub294 \uc2e4\uc218\ub97c \uc885\uc885\ud558\uace4 \ud569\ub2c8\ub2e4. \uc774\ub7f0 \uc2e4\uc218\ub97c \uc608\ubc29\ud558\uae30 \uc704\ud574 \uae30\ubcf8\uc801\uc73c\ub85c lint\ub97c \ud1b5\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \uba54\uc2dc\uc9c0\ub97c \ucd9c\ub825\ud558\uace0\uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=43748\" rel=\"attachment wp-att-43748\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.26.02-1024x133.png\" alt=\"\" width=\"750\" height=\"97\" class=\"aligncenter size-large wp-image-43748\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.26.02-1024x133.png 1024w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.26.02-300x39.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.26.02-768x100.png 768w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.26.02.png 1728w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<h2>\ud504\ub85c\uc81d\ud2b8\uc5d0 Custom Lint \uc124\uc815\ud558\uae30<\/h2>\n<p><em><strong>NOTE:\uc544\uc9c1 \ud655\uc815\ub41c API\ub4e4\uc774 \uc544\ub2c8\uae30 \ub54c\ubb38\uc5d0 \ub2e4\uc74c\ubc84\uc804\uc5d0\ub294 \ubcc0\uacbd\ub420 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/strong><\/em><\/p>\n<ol>\n<li>custom lint\ub97c \uc704\ud55c checker \ubaa8\ub4c8 \uc0dd\uc131<\/li>\n<li>\uc571 \ubaa8\ub4c8\uc758 build.gradle \uc5d0 \ub2e4\uc74c \ub0b4\uc6a9\uc744 \ucd94\uac00\ud558\uae30\n<pre class=\"lang:java decode:true\">dependencies {\r\n    lintChecks project(':checker')\/\/ \ubaa8\ub4c8 \uc774\ub984 \ud655\uc778\r\n}\r\n<\/pre>\n<\/li>\n<li>\ucd94\uac00\ud55c custom lint \ubaa8\ub4c8\uc5d0 \ub2e4\uc74c \ub0b4\uc6a9\uc744 \ucd94\uac00\ud558\uae30\n<pre class=\"lang:java decode:true\">apply plugin: 'java' \/\/\ucf54\ud2c0\ub9b0 \uc0ac\uc6a9\uc790\ub294 kotlin\uc73c\ub85c \ubcc0\uacbd\r\ndependencies {\r\n    compileOnly \"com.android.tools.lint:lint-api:26.5.0\"\r\n    compileOnly \"com.android.tools.lint:lint-checks:26.5.0\"\r\n}<\/pre>\n<p>\ucd5c\uc2e0 \ubc84\uc804\uc740 \uc774\uacf3\uc5d0\uc11c \ud655\uc778<br \/>\nhttps:\/\/mvnrepository.com\/artifact\/com.android.tools.lint\/lint-gradle-api<\/p>\n<\/li>\n<li>IssueRegistry \uc11c\ube0c \ud074\ub798\uc2a4 \uc0dd\uc131\ud558\uae30\n<pre class=\"lang:java decode:true\">public class CustomIssueRegistry extends IssueRegistry {\r\n\r\n    @Override\r\n    public int getApi() {\r\n        return ApiKt.CURRENT_API;\r\n    }\r\n\r\n    @NotNull\r\n    @Override\r\n    public List&lt;Issue&gt; getIssues() {\r\n        \/**\r\n         * \uc774\uc288 \ub4f1\ub85d\uc740 \uc774\uacf3\uc5d0\uc11c\r\n         *\/\r\n        return Arrays.asList();\r\n    }\r\n}\r\n<\/pre>\n<\/li>\n<li>custom lint \ubaa8\ub4c8\uc758 build.gradle\uc5d0 IssueRegistry \uc11c\ube0c \ud074\ub798\uc2a4 \ub4f1\ub85d\ud558\uae30\n<pre class=\"lang:java decode:true\">dependencies{ ... }\r\njar {\r\n    manifest {\r\n        attributes(\"Lint-Registry-v2\": \"com.charlezz.checker.CustomIssueRegistry\")\r\n    }\r\n}<\/pre>\n<p>CanonicalName\uc744 \uc815\ud655\ud558\uac8c \uc801\ub294\ub2e4.<\/p>\n<\/li>\n<li>lint \uac80\uc0ac\ub97c \ud558\uace0 \uc2f6\uc740 \uc774\uc288 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \ub4f1\ub85d \ud558\uae30<\/li>\n<\/ol>\n<h2>\uc774\uc288(Issue) \uc0dd\uc131\ud558\uae30<\/h2>\n<p>\uc774\uc288\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574\uc11c\ub294 Issue.create(&#8230;) \uba54\uc18c\ub4dc\ub97c \uc0ac\uc6a9\ud574\uc57c\ud569\ub2c8\ub2e4.<\/p>\n<p>\uba54\uc18c\ub4dc\uc5d0\uc11c \ub2e4\uc74c\uc758 \ub9e4\uac1c\ubcc0\uc218\ub4e4\uc744 \uac16\uc2b5\ub2c8\ub2e4.<\/p>\n<ul>\n<li>id : \uc774\uc288\uc758 \uace0\uc720 \uc2dd\ubcc4 \ubb38\uc790\uc5f4<\/li>\n<li>briefDescription : 5-6 \ubb38\uc790\ub85c \ud45c\ud604\ud558\ub294 \ubb38\uc81c\uc758 \uc9e7\uc740 \uc694\uc57d\uc744 \uc801\uc2b5\ub2c8\ub2e4.\u001c<\/li>\n<li>explanation : \uc774\uc288\uc5d0 \ub300\ud55c \uc804\uccb4 \uc124\uba85\uacfc \uc81c\uc548\uc0ac\ud56d\uc744 \uc774\uacf3\uc5d0 \uc801\uc2b5\ub2c8\ub2e4.<\/li>\n<li>category : \uc774\uc288\uc640 \uc5f0\uad00\ub41c \uce74\ud14c\uace0\ub9ac\ub97c \uc801\uc2b5\ub2c8\ub2e4. \uc608 ) Category.CORRECTNESS<\/li>\n<li>priority : \uc774\uc288\uc758 \uc6b0\uc120\uc21c\uc704\ub97c \uacb0\uc815\ud569\ub2c8\ub2e4. 1~10 \uc0ac\uc774\uc758 \uc815\uc218\ub97c \uc801\uc2b5\ub2c8\ub2e4.<\/li>\n<li>severity : \uc774\uc288\uc758 \uc2ec\uac01\ub3c4\ub97c \uc9c0\uc815\ud569\ub2c8\ub2e4.<br \/>\n\ud655\uc815\ub41c API\ub294 \uc544\ub2c8\uc9c0\ub9cc \ud604\uc7ac \ub2e4\uc74c\uacfc \uac19\uc740 \uc2ec\uac01\ub3c4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">Severity.FATAL\r\nSeverity.ERROR\r\nSeverity.WARNING\r\nSeverity.INFORMATIONAL\r\nSeverity.IGNORE<\/pre>\n<\/li>\n<li>implementation : \ubb38\uc81c\uc0ac\ud56d\uc744 \uac80\ucd9c\ud558\ub294 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc744 \ud3ec\ud568\ud55c Implementation \ud074\ub798\uc2a4\ub97c \uad6c\ud604\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n<h2>Detector \uad6c\ud604\ud558\uae30<\/h2>\n<p>Detector\ub294 \ud2b9\uc815\ubb38\uc81c\ub4e4\uc744 \uac80\ucd9c\ud558\ub294 \ud074\ub798\uc2a4\uc778\ub370,\u00a0XmlScanner \ub610\ub294 SourceCodeScanner \uc778\ud130\ud398\uc774\uc2a4\uc640 \ud568\uaed8 \uad6c\ud604\ub418\uc9c0 \uc54a\uc73c\uba74 \ub3d9\uc791\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<p>XmlScanner\ub294 xml \ud30c\uc77c \ub0b4\uc758 \ucf54\ub4dc\uc5d0\uc11c \uc624\ub958\uc0ac\ud56d\uc744 \uac80\ucd9c\ud558\uace0, SourceCodeScanner\ub294 java\ud30c\uc77c \ub0b4\uc758 \ucf54\ub4dc\uc5d0\uc11c \uc624\ub958\uc0ac\ud56d\uc744 \uac80\ucd9c\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc124\uba85\uc744 \uc704\ud574 \uac04\ub2e8\ud55c \uc608\uc81c\ub97c \ub9cc\ub4e4\uc5b4 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \ub370\uc774\ud130\ubc14\uc778\ub529 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \uc0ac\uc6a9\uc744 \uac15\uc81c\ud558\uae30 \uc704\ud574 Activity.setContentView() \ud638\ucd9c\uc744 \ub9c9\uace0,\u00a0 DatabindingUtil.setContentView()\ub97c \uc0ac\uc6a9\ud558\ub3c4\ub85d \uc720\ub3c4\ud558\ub294 \uc608\uc81c\ub97c \uc791\uc131\ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Detector\uc640 SourceCodeScanner\ub97c \uc0c1\uc18d \ud558\ub294 \uc11c\ube0c \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true \">public class SetContentViewDetector \r\n        extends Detector \r\n        implements SourceCodeScanner {\r\n\r\n}<\/pre>\n<p>\uba54\uc18c\ub4dc\uc774\ub984\uc774 setContentView\uc774\ub77c\ub294\uac83\uc5d0 \ucd08\uc810\uc744 \ub9de\ucdb0 \ud574\ub2f9 \uba54\uc18c\ub4dc \uba85\uc744 \uac80\ucd9c\ud558\ub294 \ucf54\ub4dc\ub97c \ub2e4\uc74c\uacfc \uac19\uc774 \uc791\uc131\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true \">@Nullable\r\n@Override\r\npublic List&lt;String&gt; getApplicableMethodNames() {\r\n    return Arrays.asList(\"setContentView\");\r\n}<\/pre>\n<p>getApplicableMethodName()\uc740 \ubc18\ud658\ud558\ub294 \ub9ac\uc2a4\ud2b8\uc5d0 \uc788\ub294 \uba54\uc18c\ub4dc \uc774\ub984\uc744 \uc18c\uc2a4\ucf54\ub4dc\ub85c \ubd80\ud130 \uac80\ucd9c \ud558\ub294 \uc5ed\ud560\uc744 \ud569\ub2c8\ub2e4.<\/p>\n<p>\ud574\ub2f9 \uba54\uc18c\ub4dc\ub97c \uac80\ucd9c\uc2dc \uc218\ud589\ud558\ub294 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">public static final Issue ISSUE = Issue.create(\r\n        SetContentViewDetector.class.getSimpleName(),\r\n        \"Prohibits usages of setContentView()\",\r\n        \"Prohibits usages of setContentView(), use DataBindingUtil.setContentView() instead\",\r\n        Category.CORRECTNESS,\r\n        5,\r\n        Severity.ERROR,\r\n        new Implementation(SetContentViewDetector.class, Scope.JAVA_FILE_SCOPE)\r\n);\r\n\r\n@Override\r\npublic void visitMethodCall(@NotNull JavaContext context, @NotNull UCallExpression node, @NotNull PsiMethod method) {\r\n    if (context.getEvaluator().isMemberInClass(method, \"androidx.databinding.DataBindingUtil\")) {\r\n        return;\r\n    }\r\n    context.report(\r\n            ISSUE,\r\n            node,\r\n            context.getLocation(node),\r\n            \"Use DataBindingUtil.setContentView() instead\"\r\n    );\r\n}<\/pre>\n<p>visitMethodCall\uc740 getApplicableMethodNames\uc5d0\uc11c \ubc18\ud658\ub41c \uba54\uc18c\ub4dc\uac00 \ud638\ucd9c\ub418\uba74 \ud638\ucd9c\ub418\ub294 \ucf5c\ubc31\uba54\uc11c\ub4dc \uc785\ub2c8\ub2e4. JavaContext, UCallExpression, PsiMethod\ub97c \ub9e4\uac1c\ubcc0\uc218\ub85c \uac16\ub294\ub370 \uac01 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub300\ud55c \uc124\uba85\uc740 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<ul>\n<li>JavaContext : \ubd84\uc11d\ud55c \uc790\ubc14 \ud30c\uc77c \uc5d0 \ub300\ud55c \uc815\ubcf4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n<li>UCallExpression : \ud638\ucd9c\ub41c \uba54\uc18c\ub4dc\uc758 \ub178\ub4dc\uc815\ubcf4\uc785\ub2c8\ub2e4.<\/li>\n<li>PsiMethod : \ud638\ucd9c\ub41c \uba54\uc18c\ub4dc\ub97c \ud45c\ud604\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n<p>setContentView\uac00 \uac80\ucd9c\ub418\uc5c8\ub2e4\uba74 context.report(&#8230;) \ud638\ucd9c\uc744 \ud1b5\ud574 lint\uc5d0\uac8c \uc5d0\ub7ec\ub97c \uc54c\ub9bd\ub2c8\ub2e4. \uc8fc\uc758\ud574\uc57c\ud560 \uc810\uc740\u00a0DatabindingUtil.setContentView \ub3c4 \uba54\uc18c\ub4dc \uc774\ub984\uc774 \uac19\uae30 \ub54c\ubb38\uc5d0 \ub370\uc774\ud130\ubc14\uc778\ub529 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 report\ud558\uc9c0 \uc54a\uae30 \uc704\ud574 Evaluator\ub85c \ubd80\ud130 \uba54\uc18c\ub4dc\uac00 DatabindingUtil\ud074\ub798\uc2a4\uc5d0 \uc18d\ud574 \uc788\ub294\uc9c0 \ud655\uc778\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc774\uc81c \ub9c8\uc9c0\ub9c9 \ub2e8\uacc4\uc785\ub2c8\ub2e4. \uc0dd\uc131\ud55c \uc774\uc288\ub97c CustomIssueRegistry\uc5d0 \ub4f1\ub85d\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true \">public class CustomIssueRegistry extends IssueRegistry {\r\n    ...\r\n    @NotNull\r\n    @Override\r\n    public List&lt;Issue&gt; getIssues() {\r\n        return Arrays.asList(\r\n                SetContentViewDetector.ISSUE\r\n        );\r\n    }\r\n}\r\n<\/pre>\n<p>\ubaa8\ub4e0 \uacfc\uc815\uc774 \ub05d\ub0ac\ub2e4\uba74 Clean Project\ub97c \ud558\uc5ec \ucd08\uae30\ud654\ub97c \ud55c\ubc88 \uc2dc\ucf1c\uc90d\ub2c8\ub2e4. \uc774\uc81c Activity.setContentView()\ub97c \ud638\ucd9c\ud558\uba74 lint\uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ub418\ub294\uac83\uc744 \ud655\uc778\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=43749\" rel=\"attachment wp-att-43749\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.28.56.png\" alt=\"\" width=\"900\" height=\"180\" class=\"aligncenter size-full wp-image-43749\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.28.56.png 900w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.28.56-300x60.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/09\/charles-2019-12-21-\uc624\ud6c4-4.28.56-768x154.png 768w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p>\uc704 \uc608\uc81c\ub294 <a href=\"https:\/\/github.com\/Charlezz\/LintCheck\">https:\/\/github.com\/Charlezz\/LintCheck<\/a> \uc5d0\uc11c \ud655\uc778 \uac00\ub2a5\ud569\ub2c8\ub2e4.<\/p>\n<h2>TL;DR<\/h2>\n<p>Lint\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube4c\ub4dc \ubc0f \ub7f0\ud0c0\uc784 \uc774\uc804\uc5d0 \uc624\ub958\ub97c \uac80\ucd9c\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0, \uac1c\ubc1c\uc758 \uc0dd\uc0b0\uc131\uc744 \ub192\uc774\uace0 \ud504\ub85c\uadf8\ub7a8\uc744 \uc548\uc815\ud654 \uc2dc\ud0ac \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uac04\ub2e8\ud788 Java \ucf54\ub4dc\ub97c \uc815\uc801 \ubd84\uc11d\ud558\ub294 \uc608\uc81c\ub97c \uc18c\uac1c\ud588\uc9c0\ub9cc, xml \ucf54\ub4dc\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c XmlScanner\ud1b5\ud574 \ubd84\uc11d\uc744 \ud558\uace0 \uc624\ub958\ub97c \uac80\ucd9c \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>xml \ucf54\ub4dc \ubd84\uc11d\uc744 \ud3ec\ud568\ud55c \ub2e4\uc591\ud55c \uc608\uc81c \ubc0f \ucf54\ud2c0\ub9b0 \uc0ac\uc6a9\uc608\uc81c\ub294<\/p>\n<p><a href=\"https:\/\/github.com\/alexjlockwood\/android-lint-checks-demo\">https:\/\/github.com\/alexjlockwood\/android-lint-checks-demo<\/a> \uc5d0\uc11c \ud655\uc778 \uac00\ub2a5\ud569\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lint\ub780? Android \uc2a4\ud29c\ub514\uc624\uc5d0 \uc788\ub294 Lint\ub77c\ub294 \ucf54\ub4dc \uc2a4\uce94 \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud558\uba74 \uc571\uc744 \uc2e4\ud589\ud558\uac70\ub098 \ud14c\uc2a4\ud2b8 \uc0ac\ub840\ub97c \uc791\uc131\ud558\uc9c0 \uc54a\uace0\ub3c4 \ucf54\ub4dc\uc758 \uad6c\uc870\uc801 \ubb38\uc81c\ub97c \uc2dd\ubcc4\ud558\uace0 \uc218\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub3c4\uad6c\uc5d0\uc11c \ud0d0\uc9c0\ub41c \uac01 \ubb38\uc81c\ub294 \uc124\uba85 \uba54\uc2dc\uc9c0 \ubc0f \uc2ec\uac01\ub3c4 \uc218\uc900\uacfc \ud568\uaed8 \ubcf4\uace0\ub418\ubbc0\ub85c \uac1c\uc120\uc774 \uc2dc\uae09\ud55c \uc21c\uc11c\ub300\ub85c \uc2e0\uc18d\ud788 \uc6b0\uc120\uc21c\uc704\ub97c \uacb0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub610\ud55c \ud504\ub85c\uc81d\ud2b8\uc640 \uad00\ub828\uc774 \uc5c6\ub294 \ubb38\uc81c\ub97c \ubb34\uc2dc\ud574\uc11c \ubb38\uc81c\uc758 \uc2ec\uac01\ub3c4 \uc218\uc900\uc744 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[25,26],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/13522"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=13522"}],"version-history":[{"count":4,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/13522\/revisions"}],"predecessor-version":[{"id":43750,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/13522\/revisions\/43750"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=13522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=13522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=13522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}