五陵年少金市东,银鞍白马渡春风。这篇文章主要讲述[在新计算机上运行项目或删除数据库文件夹时,未在Android Studio中创建SQLite数据库相关的知识,希望能为你提供帮助。
[我已经构建了一个应用程序,其中使用融合位置提供程序可以获取位置,并基于该位置显示来自SQLiteDatabase的特定位置的报告卡。
数据库最初运行良好,但是当我在另一台机器上运行相同的android项目时,它并没有在创建数据库。 Android在设备文件资源管理器->
数据->
数据->
包名称->
数据库中创建数据库文件夹后。我是通过右键单击“数据库”文件夹并单击“上载”来手动加载以下数据库文件的。数据库文件链接:https://drive.google.com/file/d/197MHiLl8nvFZ5eHStrBR9WfeYvQTtDKm/view?usp=sharing为了尝试了解问题所在,我也从自己的计算机上的项目中删除了数据库文件夹,现在也没有在计算机上创建数据库文件夹。
【[在新计算机上运行项目或删除数据库文件夹时,未在Android Studio中创建SQLite数据库】在将其标记为重复项之前,我已经尝试过以下问题的方法,但仍然无法使用。Android SQLite database table not being createdsqlite database not createdhttps://alvinalexander.com/android/sqliteopenhelper-does-not-call-oncreate-failing-database
请在下面找到我的代码:DatabaseHelper.java
package edu.cpsc6150.co2ut;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {public static String DATABASE_NAME = "states";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "States_Report";
public static final String KEY_ID = "id";
public static final String STATE_NAME = "name";
public static final String STATE_GRADE = "grade";
public static final String EXTREME_HEAT = "heat";
public static final String DROUGHT = "Drought";
public static final String WILDFIRES = "wildfires";
public static final String INLAND_FLOODING = "inlandflooding";
public static final String COASTAL_FLOODING = "coastalflooding";
public static final String CREATE_TABLE_STUDENTS = "CREATE TABLE "
+ TABLE_NAME + "(" + KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ STATE_NAME + " TEXT,"
+ STATE_GRADE + " TEXT,"
+ EXTREME_HEAT + " TEXT,"
+ DROUGHT + " TEXT,"
+ WILDFIRES + " TEXT,"
+ INLAND_FLOODING + " TEXT,"
+ COASTAL_FLOODING + " TEXT)";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
//Log.d("table", CREATE_TABLE_STUDENTS);
}//end DatabaseHelper constructor/**
* Functionality: Creates tables
* PreConditions: needs table names and column names
* PostConditions: Table is created
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_STUDENTS);
}//end onCreate method/**
* Functionality: Drop existing table and create new table if table already exists
* PreConditions: Database name, oldversion number and newVersion number are required to create a new table
* PostConditions: Old table should be dropped and new table should be created
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS '" + TABLE_NAME + "'");
onCreate(db);
}//end onUpgrade method
/*
public long addStudentDetail(String state, String grade, String heat, String drought, String wildfires, String iflooding, String cflooding) {
SQLiteDatabase db = this.getWritableDatabase();
// Creating content values
ContentValues values = new ContentValues();
values.put(STATE_NAME, state);
values.put(STATE_GRADE, grade);
values.put(EXTREME_HEAT, heat);
values.put(DROUGHT, drought);
values.put(WILDFIRES, wildfires);
values.put(INLAND_FLOODING, iflooding);
values.put(COASTAL_FLOODING, cflooding);
// insert row in students table
long insert = db.insert(TABLE_NAME, null, values);
return insert;
}*//**
* Functionality: Get data from database and Update UI
* PreConditions: requires existing populated database
* PostConditions: Update reportcard in the UI from the database
*/
public String[] getData(String state) {
/*SQLiteDatabase db = this.getReadableDatabase();
Cursor res =db.rawQuery( "select * from States_Report where name = '"+state+"'", null );
return res;
*/
String State = state;
String[] name = new String[7];
String password;
//SQLiteDatabase db = getWritableDatabase();
SQLiteDatabase db = this.getReadableDatabase();
String[] columns = {DatabaseHelper.STATE_NAME,DatabaseHelper.STATE_GRADE,DatabaseHelper.EXTREME_HEAT,DatabaseHelper.DROUGHT,DatabaseHelper.WILDFIRES,DatabaseHelper.INLAND_FLOODING,DatabaseHelper.COASTAL_FLOODING};
Cursor cursor =db.query(DatabaseHelper.TABLE_NAME,columns,"name = '"+state+"' ",null,null,null,null);
StringBuffer buffer= new StringBuffer();
while (cursor.moveToNext())
{
name[0] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.STATE_NAME));
name[1] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.STATE_GRADE));
name[2] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.EXTREME_HEAT));
name[3] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.DROUGHT));
name[4] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.WILDFIRES));
name[5] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.INLAND_FLOODING));
name[6] =cursor.getString(cursor.getColumnIndex(DatabaseHelper.COASTAL_FLOODING));
}return name;
}//end getData method
}//end DatabaseHelper class
ReportCardActivity.java(与该特定功能的MainActivity.java类似)
package edu.cpsc6150.co2ut;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class ReportCardActivity extends AppCompatActivity {
private static final String TAG = ReportCardActivity.class.getSimpleName();
@BindView(R.id.location_result)
TextView txtLocationResult;
@BindView(R.id.btn_start_location_updates)
Button btnStartUpdates;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 5000;
private static final int REQUEST_CHECK_SETTINGS = 100;
private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private Boolean mRequestingLocationUpdates;
private DatabaseHelper databaseHelper;
private TextView statedisplay, gradedisplay, heat, drought, wildfires, inlandFlooding,coastalFlooding;
/**
* Functionality: Instantiates the DatabaseHelper class and other UI Components like textviews
* PreConditions: DatabaseHelper and textviews must be declared
* PostConditions: Textviews are assigned and DatabaseHelper initialized
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_card);
ButterKnife.bind(this);
databaseHelper = new DatabaseHelper(this);
SQLiteDatabase db = new DatabaseHelper(this).getReadableDatabase();
statedisplay = (TextView) findViewById(R.id.statedisplay);
gradedisplay = (TextView) findViewById(R.id.gradedisplay);
heat = (TextView) findViewById(R.id.heat);
drought = (TextView) findViewById(R.id.drought);
wildfires = (TextView) findViewById(R.id.wildfires);
inlandFlooding = (TextView) findViewById(R.id.inlandFlooding);
coastalFlooding = (TextView) findViewById(R.id.coastalFlooding);
// initialize the necessary libraries
init();
// restore the values from saved instance state
restoreValuesFromBundle(savedInstanceState);
}//end onCreate method/**
* Functionality: Initializes the necessary libraries to get location updates
* PreConditions: Library's required for the location updates must be declared
* PostConditions: All necessary Libraries are intialized
*/
private void init() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationCallback = new LocationCallback() {
/**
* Functionality: Updates Last location on receiving location updates
* PreConditions: Needs to receive locationResult as a parameter
* PostConditions: Return updated last location to the UI
*/@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
// location is received
mCurrentLocation = locationResult.getLastLocation();
updateLocationUI();
}
};
mRequestingLocationUpdates = false;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}//end init method/**
* Functionality: Restores the savedState of the activity
* PreConditions: Needs the instance state to be saved
* PostConditions: Retrieve the saved state and update the UI
*/
private void restoreValuesFromBundle(Bundle savedInstanceState) {
if (savedInstanceState != null) {
if (savedInstanceState.containsKey("is_requesting_updates")) {
mRequestingLocationUpdates = savedInstanceState.getBoolean("is_requesting_updates");
}if (savedInstanceState.containsKey("last_known_location")) {
mCurrentLocation = savedInstanceState.getParcelable("last_known_location");
}
}
updateLocationUI();
}//end restoreValuesFromBundle method/**
* Functionality: Update the UI displaying the location data
* PreConditions: Requires the current location
* PostConditions: Updates the UI with the current location and the states report card from the database
*/
String state;
private void updateLocationUI() {
if (mCurrentLocation != null) {
Geocoder gcd = new Geocoder(this, Locale.getDefault());
try{
List<
Address>
addresses = gcd.getFromLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 1);
if (addresses.size() >
0) {
state = addresses.get(0).getAdminArea();
String output[] = databaseHelper.getData(state);
statedisplay.setText("State: "+output[0]);
gradedisplay.setText("Average: "+output[1]);
heat.setText("Extreme Heat: "+output[2]);
drought.setText("Drought: "+output[3]);
wildfires.setText("Wildfires: "+output[4]);
inlandFlooding.setText("Inland Flooding: "+output[5]);
coastalFlooding.setText("Coastal Flooding: "+output[6]);
/*Cursor rs = databaseHelper.getData(state);
if (rs.moveToFirst()){
// do the workString username = rs.getString(1);
String password = rs.getString(2);
//String nam = rs.getString(rs.getColumnIndex(DatabaseHelper.STATE_NAME));
//String phon = rs.getString(rs.getColumnIndex(DatabaseHelper.STATE_GRADE));
statedisplay.setText(username);
gradedisplay.setText(password);
}*///arrayList = databaseHelper.getAllStudentsList();
//tvnames.setText("");
/*for (int i = 0;
i <
arrayList.size();
i++){
tvnames.setText(tvnames.getText().toString()+", "+arrayList.get(i));
}*/}
else {
// do your stuff
}
} catch (IOException e1) {
e1.printStackTrace();
}//end try-catch block
txtLocationResult.setText(
getString(R.string.welcome_message,state)
);
// location last updated time
}
}//end updateLocationUI method/**
* Functionality: Saves the Activities current state
* PreConditions: Needs the values of mCurrentLocation and mRequestingLocationUpdates
* PostConditions: The Instance state should be saved to the Bundle
*/
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("is_requesting_updates", mRequestingLocationUpdates);
outState.putParcelable("last_known_location", mCurrentLocation);
}//end onSaveInstanceState method/**
* Functionality: Starting location updates
* PreConditions: Check whether location settings are satisfied
* PostConditions: Location updates will be requested
*/
private void startLocationUpdates() {
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this, new OnSuccessListener<
LocationSettingsResponse>
() {
@SuppressLint("MissingPermission")
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "All location settings are satisfied.");
Toast.makeText(getApplicationContext(), "Started location updates!", Toast.LENGTH_SHORT).show();
//noinspection MissingPermission
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
updateLocationUI();
}//end onSuccess method
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Attempting to upgrade " +
"location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the
// result in onActivityResult().
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(ReportCardActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.i(TAG, "PendingIntent unable to execute request.");
}//end try-catch block
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
String errorMessage = "Location settings are inadequate, and cannot be " +
"fixed here. Fix in Settings.";
Log.e(TAG, errorMessage);
Toast.makeText(ReportCardActivity.this, errorMessage, Toast.LENGTH_LONG).show();
}//end switch statement
updateLocationUI();
}//end onFailure method
});
}//end startLocationUpdates method/**
* Functionality: OnClick will start receiving location updates
* PreConditions: Permissions must be granted
* PostConditions: Location Updates started
*/
@OnClick(R.id.btn_start_location_updates)
public void startLocationButtonClick() {
// Requesting ACCESS_FINE_LOCATION using Dexter library
Dexter.withActivity(this)
.withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
mRequestingLocationUpdates = true;
startLocationUpdates();
}//end onPermissionGranted method@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (response.isPermanentlyDenied()) {
// open device settings when the permission is
// denied permanently
openSettings();
}
}//end onPermuissionDenied method@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
token.continuePermissionRequest();
}//end onPermissionRationaleShouldBeShown method
}).check();
}//end startLocationButtonClick method/**
* Functionality: Stop or pause location updates when the app pauses
* PreConditions: FusedLocationClient must be intialized
* PostConditions: Stop Location updates
*/
public void stopLocationUpdates() {
// Removing location updates
mFusedLocationClient
.removeLocationUpdates(mLocationCallback)
.addOnCompleteListener(this, new OnCompleteListener<
Void>
() {
/**
* Functionality:
* PreConditions:
* PostConditions:
*/
@Override
public void onComplete(@NonNull Task<
Void>
task) {
Toast.makeText(getApplicationContext(), "Location updates stopped!", Toast.LENGTH_SHORT).show();
}
});
}//end stopLocationUpdates method/**
* Functionality: Check whether user has granted permissions or not
* PreConditions: Needs requestCode, resultCode and data as parameters
* PostConditions: Log the ActivityResult as an error log
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
Log.e(TAG, "User agreed to make required location settings changes.");
// Nothing to do. startLocationupdates() gets called in onResume again.
break;
case Activity.RESULT_CANCELED:
Log.e(TAG, "User chose not to make required location settings changes.");
mRequestingLocationUpdates = false;
break;
}//end switch statement
break;
}//end switch statement
}//end onActivityResult method/**
* Functionality: Open settings if permissions is denied
* PreConditions: Settings URI
* PostConditions: Open Application details settings page
*/
private void openSettings() {
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}//end openSettings method/**
* Functionality: Check for permissions again onResume
* PreConditions: App must be paused or stopped before this function is called
* PostConditions: onResume the locationupdates must be resume and the UI must be updated
*/
@Override
public void onResume() {
super.onResume();
// Resuming location updates depending on button state and
// allowed permissions
if (mRequestingLocationUpdates &
&
checkPermissions()) {
startLocationUpdates();
}
updateLocationUI();
}//end onResume()/**
* Functionality: Checks if permission to access location is granted
* PreConditions: Permission must be mentioned in the manifest file
* PostConditions: Return permission granted if Uses-Permission is mentioned in the activity file
*/
private boolean checkPermissions() {
int permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
return permissionState == PackageManager.PERMISSION_GRANTED;
}//end checkPermissions method/**
* Functionality: Stops location updates when the application is paused
* PreConditions: Application must be paused
* PostConditions: Location updates must be stopped
*/
@Override
protected void onPause() {
super.onPause();
if (mRequestingLocationUpdates) {
// pausing location updates
stopLocationUpdates();
}
}//end onPause method
}//end ReportCardActivity class
让我知道您是否需要有关代码或依赖项的更多信息。
答案我相信正在创建数据库BUT,您似乎没有在填充它。
使用您的Databasehelper(仅将addStudentDetail注释为唯一更改),然后使用:-
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHelper = new DatabaseHelper(this);
mDBHelper.addStudentDetail("STATE1","GRADE1","HIGH","YES","NO","NO","NO");
mDBHelper.addStudentDetail("STATE1","GRADE2","HIGH","YES","NO","NO","NO");
mDBHelper.addStudentDetail("STATE1","GRADE3","HIGH","YES","NO","NO","NO");
mDBHelper.addStudentDetail("STATE1","GRADE4","HIGH","YES","NO","NO","NO");
for (String s: mDBHelper.getData("STATE1")){
Log.d("INFO",s);
}
}
}
结果:-
12-05 16:38:19.211 3764-3764/? D/INFO: STATE1
12-05 16:38:19.211 3764-3764/? D/INFO: GRADE4
12-05 16:38:19.211 3764-3764/? D/INFO: HIGH
12-05 16:38:19.211 3764-3764/? D/INFO: YES
12-05 16:38:19.211 3764-3764/? D/INFO: NO
12-05 16:38:19.211 3764-3764/? D/INFO: NO
12-05 16:38:19.211 3764-3764/? D/INFO: NO
我看不到您在代码中向数据库添加数据的任何地方。相反,您只是尝试使用
String output[] = databaseHelper.getData(state);
来获取数据,因为没有数据,它不会检索任何内容。另一答案下面我附加了一个解决方案,您只需要在ReportCardActivity.java代码中添加两行代码即可。要添加的两行代码被注释为“ // add this line”,并在其前后有一行astrix(*)。
private Boolean mRequestingLocationUpdates;
DatabaseHelper databaseHelper;
*********************************************************
SQLiteDatabase database;
//add this line
*********************************************************
private TextView statedisplay, gradedisplay, heat, drought, wildfires, inlandFlooding,coastalFlooding;
/**
* Functionality: Instantiates the DatabaseHelper class and other UI Components like textviews
* PreConditions: DatabaseHelper and textviews must be declared
* PostConditions: Textviews are assigned and DatabaseHelper initialized
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report_card);
ButterKnife.bind(this);
databaseHelper = new DatabaseHelper(this);
*********************************************************
database = databaseHelper.getWritableDatabase();
//add this line
*********************************************************
statedisplay = (TextView) findViewById(R.id.statedisplay);
gradedisplay = (TextView) findViewById(R.id.gradedisplay);
heat = (TextView) findViewById(R.id.heat);
drought = (TextView) findViewById(R.id.drought);
wildfires = (TextView) findViewById(R.id.wildfires);
inlandFlooding = (TextView) findViewById(R.id.inlandFlooding);
coastalFlooding = (TextView) findViewById(R.id.coastalFlooding);
// initialize the necessary libraries
init();
// restore the values from saved instance state
restoreValuesFromBundle(savedInstanceState);
}//end onCreate method
您粘贴代码的人运行该应用程序。这应该在设备文件资源管理器-> 数据-> 数据-> 包名称目录中创建数据库目录。
该数据库文件夹可能不会立即显示。运行一次应用程序后,您可能必须重新启动android studio。
当您重新启动android studio并转到设备文件资源管理器-> 数据-> 数据-> 包名称目录时,应创建数据库目录。
创建后,右键单击数据库文件夹,然后单击上载,然后上载您在链接中提供的数据库文件。
推荐阅读
- 以HTML集成WhatsApp jQuery
- 文件的目录查找失败…在操作系统中。 …找不到App_Data /…mdf
- Github页面和React App不管使用什么方法都无法工作
- 如何使用Android的Camera2 API
- 为什么Android测试运行器报告“空测试套件”()
- 如何在Android应用程序中启用TLS 1.2支持(在Android 4.1 JB上运行)
- Android游戏(Canvas还是OpenGL())
- “画布(Android Studio中试图绘制太大的位图”问题)
- 使用Google Apps脚本搜索无结果