커뮤니티
포인트
쿠폰
내 강의실
국비 신청 내역
증명서
계정
로그아웃
학습 질문
개발 일지
나의 활동
답변 완료
구글 에드몹 광고 실행 오류
[왕초보] 플러터(Flutter)로 시작하는 앱개발 종합반 v0
5주차
북마크
정*수
댓글
2
추천
0
조회수
11
조회수
11
답변 완료

* 겪고 있는 문제 상황을 최대한 자세하게 작성해주세요.

* 문제 해결을 위해 어떤 시도를 해보았는지 구체적으로 함께 알려주세요.


5주차 강의 입니다.


main.dart 에는 숫자1이 표기 되어 있고,

pubspec.yaml에는 느낌표(!) 표시가 나옵니다.


그리고 아래 메세지와 같이 계속 진행을 못하고 있습니다.


어떤 부분이 잘못 된건가요??



스파르타 즉문즉답

DEBUG CONSOLE


Launching lib\main.dart on sdk gphone64 x86 64 in debug mode...

Checking the license for package Android SDK Platform 31 in C:\Users\kemsz\AppData\Local\Android\sdk\licenses

License for package Android SDK Platform 31 accepted.

Preparing "Install Android SDK Platform 31 (revision: 1)".

"Install Android SDK Platform 31 (revision: 1)" ready.

Installing Android SDK Platform 31 in C:\Users\kemsz\AppData\Local\Android\sdk\platforms\android-31

"Install Android SDK Platform 31 (revision: 1)" complete.

"Install Android SDK Platform 31 (revision: 1)" finished.

ERROR:D8: Cannot fit requested classes in a single dex file (# methods: 78752 > 65536)

com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 

The number of method references in a .dex file cannot exceed 64K.

Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html

at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:151)

at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:138)

at com.android.build.gradle.internal.tasks.DexMergingWorkAction.merge(DexMergingTask.kt:859)

at com.android.build.gradle.internal.tasks.DexMergingWorkAction.run(DexMergingTask.kt:805)

at com.android.build.gradle.internal.profile.ProfileAwareWorkAction.execute(ProfileAwareWorkAction.kt:74)

at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)

at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)

at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)

at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)

at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)

at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)

at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)

at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)

at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)

at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)

at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)

at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)

at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)

at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)

at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)

at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)

at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)

at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:205)

at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)

at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:187)

at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:120)

at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:162)

at org.gradle.internal.Factories$1.create(Factories.java:31)

at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249)

at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109)

at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:114)

at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:157)

at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:126)

at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)

at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)

at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)

at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)

at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)

at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)

at java.base/java.lang.Thread.run(Thread.java:833)

Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, position: null

at Version.fakeStackEntry(Version_3.3.70.java:0)

at com.android.tools.r8.internal.Fj.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:75)

at com.android.tools.r8.internal.Fj.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:28)

at com.android.tools.r8.internal.Fj.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:27)

at com.android.tools.r8.internal.Fj.b(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:2)

at com.android.tools.r8.D8.run(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:11)

at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:136)

... 38 more

Caused by: com.android.tools.r8.internal.f: Cannot fit requested classes in a single dex file (# methods: 78752 > 65536)

at com.android.tools.r8.internal.JT.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:14)

at com.android.tools.r8.internal.JT.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:22)

at com.android.tools.r8.internal.n30.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:524)

at com.android.tools.r8.internal.i30.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:7)

at com.android.tools.r8.internal.F2.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:371)

at com.android.tools.r8.internal.F2.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:455)

at com.android.tools.r8.D8.d(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:756)

at com.android.tools.r8.D8.b(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:1)

at com.android.tools.r8.internal.Fj.a(R8_3.3.70_49b71801b8b3de79ea68cec3bf950786c8f90f7a560cea4a2d23a82079b17d04:24)

... 41 more


FAILURE: Build failed with an exception.


* What went wrong:

Execution failed for task ':app:mergeExtDexDebug'.

> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate

  > There was a failure while executing work items

   > A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingWorkAction

     > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:

      The number of method references in a .dex file cannot exceed 64K.

      Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html


* Try:

> Run with --stacktrace option to get the stack trace.

> Run with --info or --debug option to get more log output.

> Run with --scan to get full insights.


* Get more help at https://help.gradle.org


BUILD FAILED in 3m 48s

[!] App requires Multidex support

  Multidex support is required for your android app to build since the number of methods has exceeded 64k. See https://docs.flutter.dev/deployment/android#enabling-multidex-support for more information. You may pass the --no-multidex flag to skip Flutter's multidex support to use a manual solution.

  Flutter tool can add multidex support. The following file will be added by flutter:

    android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java

cannot prompt without a terminal ui

Exception: Gradle task assembleDebug failed with exit code 1

Exited (sigterm)





작성한 코드 및 에러 메세지

import 'dart:io';


import 'package:flutter/cupertino.dart';

import 'package:flutter/material.dart';

import 'package:google_mobile_ads/google_mobile_ads.dart';

import 'package:provider/provider.dart';

import 'package:shared_preferences/shared_preferences.dart';


import 'memo_service.dart';


late SharedPreferences prefs;


void main() async {

  WidgetsFlutterBinding.ensureInitialized();

  prefs = await SharedPreferences.getInstance();

  MobileAds.instance.initialize();


  runApp(

    MultiProvider(

      providers: [

        ChangeNotifierProvider(create: (context) => MemoService()),

      ],

      child: const MyApp(),

    ),

  );

}


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      debugShowCheckedModeBanner: false,

      home: HomePage(),

    );

  }

}


// 홈 페이지

class HomePage extends StatefulWidget {

  const HomePage({super.key});


  @override

  State<HomePage> createState() => _HomePageState();

}


class _HomePageState extends State<HomePage> {

  final BannerAd myBanner = BannerAd(

    // Test 광고 ID, 광고 승인받은 후 생성한 광고 unit ID 로 바꾸기

    adUnitId: Platform.isAndroid

        ? 'ca-app-pub-3940256099942544/6300978111' // Android ad unit ID

        : 'ca-app-pub-3940256099942544/2934735716', // iOS ad unit ID

    size: AdSize.fullBanner,

    request: AdRequest(),

    listener: BannerAdListener(

      onAdFailedToLoad: (ad, error) {

        ad.dispose();

      },

    ),

  );


  @override

  void initState() {

    // TODO: implement initState

    super.initState();

    myBanner.load();

  }


  @override

  Widget build(BuildContext context) {

    return Consumer<MemoService>(

      builder: (context, memoService, child) {

        // memoService로 부터 memoList 가져오기

        List<Memo> memoList = memoService.memoList;


        return Scaffold(

          appBar: AppBar(

            title: Text("mymemo"),

          ),

          body: memoList.isEmpty

              ? Center(child: Text("메모를 작성해 주세요"))

              : ListView.builder(

                  itemCount: memoList.length, // memoList 개수 만큼 보여주기

                  itemBuilder: (context, index) {

                    Memo memo = memoList[index]; // index에 해당하는 memo 가져오기

                    return ListTile(

                      // 메모 고정 아이콘

                      leading: IconButton(

                        icon: Icon(CupertinoIcons.pin),

                        onPressed: () {

                          print('$memo : pin 클릭 됨');

                        },

                      ),

                      // 메모 내용 (최대 3줄까지만 보여주도록)

                      title: Text(

                        memo.content,

                        maxLines: 3,

                        overflow: TextOverflow.ellipsis,

                      ),

                      onTap: () {

                        // 아이템 클릭시

                        Navigator.push(

                          context,

                          MaterialPageRoute(

                            builder: (_) => DetailPage(

                              index: index,

                            ),

                          ),

                        );

                      },

                    );

                  },

                ),

          floatingActionButton: FloatingActionButton(

            child: Icon(Icons.add),

            onPressed: () {

              // + 버튼 클릭시 메모 생성 및 수정 페이지로 이동

              memoService.createMemo(content: '');

              Navigator.push(

                context,

                MaterialPageRoute(

                  builder: (_) => DetailPage(

                    index: memoService.memoList.length - 1,

                  ),

                ),

              );

            },

          ),

          bottomNavigationBar: Container(

            alignment: Alignment.center,

            width: myBanner.size.width.toDouble(),

            height: myBanner.size.height.toDouble(),

            child: AdWidget(ad: myBanner),

          ),

        );

      },

    );

  }

}


// 메모 생성 및 수정 페이지

class DetailPage extends StatelessWidget {

  DetailPage({super.key, required this.index});


  final int index;


  TextEditingController contentController = TextEditingController();


  @override

  Widget build(BuildContext context) {

    MemoService memoService = context.read<MemoService>();

    Memo memo = memoService.memoList[index];


    contentController.text = memo.content;


    return Scaffold(

      appBar: AppBar(

        actions: [

          IconButton(

            onPressed: () {

              // 삭제 버튼 클릭시

              showDeleteDialog(context, memoService);

            },

            icon: Icon(Icons.delete),

          )

        ],

      ),

      body: Padding(

        padding: const EdgeInsets.all(16),

        child: TextField(

          controller: contentController,

          decoration: InputDecoration(

            hintText: "메모를 입력하세요",

            border: InputBorder.none,

          ),

          autofocus: true,

          maxLines: null,

          expands: true,

          keyboardType: TextInputType.multiline,

          onChanged: (value) {

            // 텍스트필드 안의 값이 변할 때

            memoService.updateMemo(index: index, content: value);

          },

        ),

      ),

    );

  }


  void showDeleteDialog(BuildContext context, MemoService memoService) {

    showDialog(

      context: context,

      builder: (context) {

        return AlertDialog(

          title: Text("정말로 삭제하시겠습니까?"),

          actions: [

            // 취소 버튼

            TextButton(

              onPressed: () {

                Navigator.pop(context);

              },

              child: Text("취소"),

            ),

            // 확인 버튼

            TextButton(

              onPressed: () {

                memoService.deleteMemo(index: index);

                Navigator.pop(context); // 팝업 닫기

                Navigator.pop(context); // HomePage 로 가기

              },

              child: Text(

                "확인",

                style: TextStyle(color: Colors.pink),

              ),

            ),

          ],

        );

      },

    );

  }

}






pubspec.yaml

name: mymemo_admob

description: A new Flutter project.

# The following line prevents the package from being accidentally published to

# pub.dev using `flutter pub publish`. This is preferred for private packages.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev


# The following defines the version and build number for your application.

# A version number is three numbers separated by dots, like 1.2.43

# followed by an optional build number separated by a +.

# Both the version and the builder number may be overridden in flutter

# build by specifying --build-name and --build-number, respectively.

# In Android, build-name is used as versionName while build-number used as versionCode.

# Read more about Android versioning at https://developer.android.com/studio/publish/versioning

# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.

# Read more about iOS versioning at

# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html

# In Windows, build-name is used as the major, minor, and patch parts

# of the product and file versions while build-number is used as the build suffix.

version: 1.0.0+1


environment:

  sdk: '>=3.0.5 <4.0.0'


# Dependencies specify other packages that your package needs in order to work.

# To automatically upgrade your package dependencies to the latest versions

# consider running `flutter pub upgrade --major-versions`. Alternatively,

# dependencies can be manually updated by changing the version numbers below to

# the latest version available on pub.dev. To see which dependencies have newer

# versions available, run `flutter pub outdated`.

dependencies:

  flutter:

    sdk: flutter


  # The following adds the Cupertino Icons font to your application.

  # Use with the CupertinoIcons class for iOS style icons.

  cupertino_icons: ^1.0.2

  provider: ^6.0.3

  shared_preferences: ^2.0.15

  google_mobile_ads: ^2.0.1


dev_dependencies:

  flutter_test:

    sdk: flutter


  # The "flutter_lints" package below contains a set of recommended lints to

  # encourage good coding practices. The lint set provided by the package is

  # activated in the `analysis_options.yaml` file located at the root of your

  # package. See that file for information about deactivating specific lint

  # rules and activating additional ones.

  flutter_lints: ^2.0.0


# For information on the generic Dart part of this file, see the

# following page: https://dart.dev/tools/pub/pubspec


# The following section is specific to Flutter packages.

flutter:


  # The following line ensures that the Material Icons font is

  # included with your application, so that you can use the icons in

  # the material Icons class.

  uses-material-design: true


  # To add assets to your application, add an assets section, like this:

  # assets:

  #   - images/a_dot_burr.jpeg

  #   - images/a_dot_ham.jpeg


  # An image asset can refer to one or more resolution-specific "variants", see

  # https://flutter.dev/assets-and-images/#resolution-aware


  # For details regarding adding assets from package dependencies, see

  # https://flutter.dev/assets-and-images/#from-packages


  # To add custom fonts to your application, add a fonts section here,

  # in this "flutter" section. Each entry in this list should have a

  # "family" key with the font family name, and a "fonts" key with a

  # list giving the asset and other descriptors for the font. For

  # example:

  # fonts:

  #   - family: Schyler

  #     fonts:

  #       - asset: fonts/Schyler-Regular.ttf

  #       - asset: fonts/Schyler-Italic.ttf

  #         style: italic

  #   - family: Trajan Pro

  #     fonts:

  #       - asset: fonts/TrajanPro.ttf

  #       - asset: fonts/TrajanPro_Bold.ttf

  #         weight: 700

  #

  # For details regarding fonts from package dependencies,

  # see https://flutter.dev/custom-fonts/#from-packages





취소
 공유
취소
댓글 0
댓글 알림
나의얼굴