>

저는 Java의 초보자이며 Android Studio를 사용하고 있습니다. 설치 후 내 앱이 시작되지 않습니다. 소스 코드와 XML을 확인하면 오류가없는 것 같습니다. 아래 코드를 확인하도록 도와주세요

MainActivity.java

public class MainActivity extends AppCompatActivity {
    ArrayList<File> list;
    GridView gridView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gridView = (GridView)findViewById(R.id.image_grid);
        list = imageReader(Environment.getExternalStorageDirectory());
        gridView.setAdapter(new gridAdapter());
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(MainActivity.this, FullImageActivity.class);
                intent.putExtra("img", list.get(i).toString());
                startActivity(intent);
            }
        });

    }
    public class gridAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            return list.size();
        }
        @Override
        public Object getItem(int i) {
            return list.get(i);
        }
        @Override
        public long getItemId(int i) {
            return 0;
        }
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            View convertView = null;
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.row_layout, viewGroup, false);
                ImageView myImage = (ImageView) convertView.findViewById(R.id.my_image);
                myImage.setImageURI(Uri.parse(list.get(i).toString()));
            }
            return convertView;
        }
    }
    private ArrayList<File> imageReader(File externalStorageDirectory) {
        ArrayList<File> b = new ArrayList<>();
        File[] files = externalStorageDirectory.listFiles();
        for (int i =0; i<files.length; i++){
            if (files[i].isDirectory()){
                b.addAll(imageReader(files[i]));
            }else {
                if (files[i].getName().endsWith(".jpg")) {
                    b.add(files[i]);
                }
            }
        }
        return b;
    }
}


이것은 activity_main.xml입니다

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
    <GridView
        android:id="@+id/image_grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="auto_fit"
        android:columnWidth="100dp"
        android:verticalSpacing="100dp"
        android:horizontalSpacing="10dp"
        android:stretchMode="spacingWidthUniform" />
</RelativeLayout>


FullImageActivity.java입니다

public class FullImageActivity extends AppCompatActivity {
    ImageView fullImage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_full_image);
        fullImage = (ImageView)findViewById(R.id.full_image);
        String data = getIntent().getExtras().getString("img");
        fullImage.setImageURI(Uri.parse(data));
    }
}


activity_full_image.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".FullImageActivity">
    <ImageView
        android:id="@+id/full_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/wp"
        />
</RelativeLayout>

row_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/wp"
        />
</RelativeLayout>

나의 깊숙이 먹는 질문에 참석하면 기쁘다.

이것은 LOGCAT입니다

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
                                                                                   at com.jkjworks.galleryextra.FullImageActivity.onCreate(FullImageActivity.java:19)
                                                                                   at android.app.Activity.performCreate(Activity.java:7030


# 2 업데이트 매니페스트 및 BUILD.GRADLE

이것은 매니페스트입니다

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"/>
            <activity android:name=".FullImageActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>     


이것은 APP 레벨 Build.gradle입니다

 android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.domain.galleryextra"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    compile 'com.android.support:multidex:1.0.3'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    implementation 'com.google.android.gms:play-services-ads:12.0.1'
    implementation 'com.android.support:support-vector-drawable:27.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'    


  • 답변 # 1

    당신은 list.get(i) 를 확신합니까   null 가 아닙니다 ? 중단 점을 넣고 list.get(i) 의 반환 값을 분석합니다.  전달하는 것이 유효한 데이터인지 확인하십시오.

    또한 intent.getStringExtra("img") 사용   getIntent().getExtras().getString("img") 대신

    문제는 그 getIntent() 입니다   NULL 를 받고있다  그리고 당신은 그것에 액세스하려고, 따라서 NullPointerException  일어나기 위해.

    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
                                                                                       at com.merizekworks.galleryextra.FullImageActivity.onCreate(FullImageActivity.java:19)
    
    

    편집 (디버그 방법에 대한 빠른 분석) 가장 좋은 방법은 디버거를 통해 코드를 단계별로 실행하는 것입니다. 이 작업을 수행하지 않은 경우 실제로 수행하기가 매우 쉽고 문제가 무엇인지 확인할 수 있습니다.

    MainActivity 에서  이것을 바꾸십시오 :

    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Intent intent = new Intent(MainActivity.this, FullImageActivity.class);
        intent.putExtra("img", list.get(i).toString());
        startActivity(intent);
    }
    
    

    이렇게하면 좀 더 쉽게 디버깅 할 수 있습니다 :

    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        Intent intent = new Intent(MainActivity.this, FullImageActivity.class);
        File selectedFile = list.get(i); //PUT BREAKPOINT ON THIS LINE
        String filePath = selectedFile.toString();
        intent.putExtra("img", filePath );
        startActivity(intent);
    }
    
    

    참고 : 코드 디버깅에 익숙하지 않다면 몇 분 동안이 기사를 읽는 것이 좋습니다. 제 생각에는 프로그래머가 가지고있는 가장 귀중한 도구입니다. Android Studio에서 디버깅하는 방법을 알아 보려면 여기를 클릭하십시오

    왼쪽의 빨간색 원은 중단 점이며, 코드는 여기서 실행을 중지하고 위의 스크린 샷에서 볼 수 있듯이 각 변수를 분석 할 수 있습니다. 앱이 실행 중이고 중단 점이 실행을 일시 중지 한 상태에서도 "표현식 평가"를 수행 할 수 있습니다. 그렇게하면 메모리에있는 모든 객체를 잡고 테스트 할 수 있습니다.

    예를 들어 위에서 설정 한 중단 점으로 "디버그"탭에있는 "표현식 평가"버튼을 사용할 수 있습니다 :

    AndroidStudio 디버거를 사용하는 방법에 대한 기사에서 표현식을 평가하는 방법에 대한 간단한 스크린 샷입니다 (여기에서 전체 안내서) :

    <시간>

    업데이트 # 2

    참고 : API 23 이상을 사용하는 경우 다음을 확인해야합니다. Android 기기에서 읽기/쓰기 권한이 있습니다.

    당신의 AndroidManifest.xml 에서   Manifest 내부  태그 포함 :

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
    

    여기에 프로젝트에서 사용하는 솔루션이 있는데, 특히 여러 권한을 요청하려는 경우 특히 효과적입니다.

    public class MainActivity extends AppCompatActivity {
        private final String TAG = "DEBUG";
        private Activity activity;
        private ArrayList<File> list;
        private GridView gridView;
        private final int REQUEST_PERMISSIONS_CODE = 1;
        private String[] PERMISSIONS = {
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
        };
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            int totalGrantedCount = 0;
            for(int x=0; x < grantResults.length; x++){
                if (grantResults[x] == PackageManager.PERMISSION_GRANTED){
                    totalGrantedCount++;
                }
            }
            if(totalGrantedCount == grantResults.length){
                startApp();
            }else{
                boolean somePermissionsForeverDenied = false;
                for(String permission: permissions){
                    if(ActivityCompat.shouldShowRequestPermissionRationale(this, permission)){
                        //denied
                        Log.d(TAG, "PERMISSIONS: DENIED " + permission);
                    }else{
                        if(ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED){
                            //allowed
                            Log.d(TAG, "PERMISSIONS: ALLOWED " + permission);
                        } else{
                            //set to never ask again
                            somePermissionsForeverDenied = true;
                        }
                    }
                }
                if(somePermissionsForeverDenied){
                    final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
                    alertDialogBuilder.setTitle("Permissions Required")
                            .setMessage("You have forcefully denied some of the required permissions " +
                                    "for this action. Please open settings, go to permissions and allow them manually.")
                            .setPositiveButton("Settings", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                                            Uri.fromParts("package", getPackageName(), null));
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            })
                            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                }
                            })
                            .setCancelable(false)
                            .create()
                            .show();
                }else{
                    new AlertDialog.Builder(this)
                            .setTitle("PERMISSIONS DENIED")
                            .setMessage("Unable to proceed, this application requires that permissions be accepted to operate correctly. \r\n\r\n YOU MUST APPROVE ALL PERMISSIONS BEFORE CONTINUING.")
                            .setPositiveButton("TAP HERE TO CLOSE AND TRY AGAIN.", new DialogInterface.OnClickListener(){
                                public void onClick(DialogInterface dialog, int which){
                                    activity.finish();
                                    System.exit(0);
                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .setCancelable(false)
                            .show();
                }
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            this.activity = this;
            //REQUIRED FOR API 23+ - REQUEST FOR PERMISSIONS - ONLY REQUIRED TO BE DONE ONCE PER APP INSTALL.
            int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // We don't have permission so prompt the user
                ActivityCompat.requestPermissions(
                        this,
                        PERMISSIONS,
                        REQUEST_PERMISSIONS_CODE);
            }else{
                startApp();
            }
        }
        public void startApp(){
            gridView = (GridView)findViewById(R.id.image_grid);
            list = imageReader(Environment.getExternalStorageDirectory());
            gridView.setAdapter(new gridAdapter());
            gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Intent intent = new Intent(MainActivity.this, FullImageActivity.class);
                    intent.putExtra("img", list.get(i).toString());
                    startActivity(intent);
                }
            });
        }
        public class gridAdapter extends BaseAdapter {
            @Override
            public int getCount() {
                return list.size();
            }
            @Override
            public Object getItem(int i) {
                return list.get(i);
            }
            @Override
            public long getItemId(int i) {
                return 0;
            }
            @Override
            public View getView(int i, View view, ViewGroup viewGroup) {
                View convertView = null;
                if (convertView == null) {
                    convertView = getLayoutInflater().inflate(R.layout.row_layout, viewGroup, false);
                    ImageView myImage = (ImageView) convertView.findViewById(R.id.my_image);
                    myImage.setImageURI(Uri.parse(list.get(i).toString()));
                }
                return convertView;
            }
        }
        private ArrayList<File> imageReader(File externalStorageDirectory) {
            ArrayList<File> b = new ArrayList<>();
            File[] files = externalStorageDirectory.listFiles();
            for (int i =0; i<files.length; i++){
                if (files[i].isDirectory()){
                    b.addAll(imageReader(files[i]));
                }else {
                    if (files[i].getName().endsWith(".jpg")) {
                        b.add(files[i]);
                    }
                }
            }
            return b;
        }
    }
    
    

관련 자료

  • 이전 jsf - - 잘못된 매개 변수를 자동으로 무시
  • 다음 python - 점 군집에서 선을 식별하는 방법은 무엇입니까?